python学习(第二章)
2013-02-11 14:21
141 查看
列表和元组
本章首先对序列做一个预览,接下来讲解所有序列(包括元组和列表)都通用的操作。而这些操作同样适用于字符串序列概览
python包含6个内建序列,分别为列表、元组、字符串、Unicode字符串、buffer对象和xrange对象列表和元组的主要区别在于,列表可以修改,元组则不能
python中有一个名为容器(container)的数据结构。序列和映射是两类主要的容器。序列的每个元素都有自己的编号,而映射中的每个元素都有一个名字(即键)。
通用的序列操作
索引
序列中的所有元素都是有编号的--从0开始递增。>>>greeting = 'Hello' >>>greeting[0] 'H'
使用负数索引时,python会从右边,也就是从最后1个开始计数
>>>greeting[-1] 'o'
字符串字面值能够直接使用索引,而不需要一个变量引用它们。
>>>'Hello'[1] 'e'
如果一个函数调用返回一个序列,那么可以直接对返回结果进行索引。
>>>fourth = raw_input('Year: ')[3] Year: 2005 >>>fourth '5'
示例2-1:
#根据给定的年 月 日以数字形式打印初日期 months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] #以1~31的数字作为结尾的列表 endings = ['st', 'nd', 'rd'] + 17 * ['th'] \ + ['st', 'nd', 'rd'] + 7 * ['th'] \ + ['st'] year = raw_input('Year: ') month = raw_input('Month (1-12): ') day = raw_input('Day (1-31): ') month_number = int(month) day_number = int(day) #记得要将月份和天数减1,以获得正确的索引 month_name = months[month_number - 1] day_name = day + endings[day_number - 1] print month_day + ' ' + day_name + ', ' + year
$./2-1.py Year: 2013 Month (1 - 12): 1 Day (1 - 31): 26 January 26th, 2013
分片
与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围的元素。分片通过冒号相隔的两个索引来实现>>>tag = '<a href="http://www.python.org">Python web site</a>' >>>tag[9: 30] 'http://www.python.org' >>>tag[32: -4] 'Python web site'
第一个索引是需要提取部分的第一个元素的编号,而最后的索引则是分片之后剩下部分的第一个元素的编号
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[3: 6] [4, 5, 6] >>>numbers[0: 1] [1]
优雅的捷径
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[7: 10] [8, 9, 10] >>>numbers[-3: ] [8, 9, 10]
实际上,只要分片中最左边的索引比它右边的晚出现在序列中,结果就是一个空序列。幸好,可以使用一个捷径:**如果分片所得部分包括序列结尾的元素,那么,组需置空最后一个索引即可
这种方法同样使用于序列开始的元素:
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[0: 3] [1, 2, 3] >>>numbers[: 3] [1, 2, 3]
实际上,如果需要复制整个序列,可以将两个索引都置空:
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[: ] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
示例2-2:
# 对http://www.something.org形式的URL进行分割 url = raw_input('Please enter the URL: ') domain = url[11: -4] print "Domain name: " + domain
Please enter the URL: http://www.baidu.com Domain name: baidu
更大的步长
进行分片的时候,分片的开始和结束点需要进行制定。而另一个参数(在python2.3加入到内建类型)--步长(step length)--通常是隐式设置的。在普通的分片中,步长是1--分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[0: 10] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[0: 10: 1] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[0: 10: 2] [1, 3, 5, 7, 9]
当然,步长不能为0--那不会向下执行--当步长可以是负数,即从右到左提取元素,当在这里要求开始点(开始索引)大于结束点:
>>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>>numbers[8: 3: -1] [9, 8, 7, 6, 5] >>>numbers[10: 0: -2] [10, 8, 6, 4, 2]
序列相加
通过使用加号(+)可以进行序列的链接操作:>>>[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] >>>'Hello, ' + 'World' 'Hello, World'
列表和字符串是无法链接在一起的,尽管他们都是序列。简单的来说,两种相同类型的序列才能进行链接操作
>>>[1, 2, 3] + 'world' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "str") to list
乘法
用数字x乘以一个序列会产生新的序列,而在新的序列中,原来的序列将被重复x次。>>>'python' * 5 'pythonpythonpythonpythonpython' >>>[42] * 10 [42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
None、空列表和初始化
空列表可以通过两个中括号进行表示([])有时候需需要一个值来代表控制--意味着没有在里面放置任何元素。这个时候就需要使用None。None是一个python的内建值,它的确切含义是“这里什么也没有”。
>>>sequence = [None] * 10 >>>sequence [None, None, None, None, None, None, None, None, None, None]
示例2-3
# 以正确的跨度在居中的“盒子”内打印一个句子 # 注意,整数除法运算(//)只能在python2.2及后续版本,在之前的版本中, # 只能使用普通除法(/) sentence = raw_input('Sentence: ') screen_width = 80 text_width = len(sentence) box_width = text_width + 6 left_margin = (screen_width - box_width) // 2 print print ' ' * left_margin + '+' + '-' * (box_width - 2) + '+' print ' ' * left_margin + '| ' + ' ' * text_width + ' |' print ' ' * left_margin + '| ' + sentence + ' |' print ' ' * left_margin + '| ' + text_width + ' |' print ' ' * left_margin + '+' + (box_width - 2) + '+' print
$./2-3.py Sentence: hello world +---------------+ | | | hello world | | | +---------------+
成员资格
为了检查一个值是否在序列中,可以使用in运算符,**这个运算符检查某个条件是否为真,然后返回相应的值: 条件为真返回True,条件为假返回False。>>>permission = 'rw' >>>'w' in permission True >>>'x' in permission False >>>users = ['mlh', 'foo', 'bar'] >>>raw_input('Enter your uesr name: ') in users Enter your uesr name: mlh True >>> subject = '$$$ Get rich now!!! $$$' >>> '$$$' in subject
尝试去检查子字符串,只能用在python2.3及后续版本
示例2-4
# 检查用户名和PIN码 database = [ ['albert', '1234'], ['dilbert', '4242'], ['smith', '7524'], ['jones', '9843'] ] username = raw_input('User name: ') pin = raw_input('PIN code: ') if [username, pin] in database: print 'Access granted'
$./2-4.py User name: albert PIN code: 1234 Access granted
长度、最小值和最大值
内建函数len、min和max>>>numbers = [1, 2, 3, 4] >>>len(numbers) 4 >>>max(numbers) 4 >>>min(numbers) 1 >>>max(2, 3) 3 >>>min(9, 2, 8, 4) 2
列表: python的“苦力”
list函数
list函数可以实现: 根据字符串创建列表。>>>list('Hello') ['H', 'e', 'l', 'l', 'o']
list函数适用于所有类型的序列,而不只是字符串
可以用下面的表达式将一个由字符组成的序列转换成字符串:
''.join(somelist)
在这里,somelist是需要转换的列表。
基本的列表操作
列表可以使用所有适用于序列的标准操作,例如索引、分片、连接和乘法。有趣的是,列表是可以修改的修改列表: 元素赋值
使用索引标记来为某个特定的、位置明确的元素赋值
>>>x = [1, 1, 1] >>>x[1] = 2 >>>x [1, 2, 1]
[注: 不能为一个位置不存在额元素进行赋值。]
删除元素
使用del语句从列表中删除元素
>>>names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl'] >>>del names[2] >>>names ['Alice', 'Beth', 'Dee-Dee', 'Earl']
分片赋值
>>>name = list('Perl') >>>name ['P', 'e', 'r', 'l'] >>>name[2: ] = list('ar') >>>name ['P', 'e', 'a', 'r']
在使用分片赋值时,可以使用与原序列不等长的序列将分片替换。
>>>name = list('Perl') >>>name[1: ] = list('ython') >>>name ['P', 'y', 't', 'h', 'o', 'n']
通过分批赋值来删除元素也是可行的: "替换"一个空的分片。
>>>numbers = [1, 2, 3, 4, 5] >>>numbers[1: 4] = [] >>>numbers [1, 5]
列表方法
方法是一个与某些对象有紧密联系的函数,对象可能是列表、数字,也可能是字符串或者其他类型对象。一般来说,方法可以这样进行调用:对象.方法(参数)
append
append方法用于在列表末尾追加新的对象:
>>>lst = [1, 2, 3] >>>lst.append(4) >>>lst [1, 2, 3, 4] >>> lst.append([4, 5, 6]) >>> lst [1, 2, 3, [4, 5, 6]]
count
count方法统计某个元素在列表中出现的次数
>>>['to', 'be', 'or', 'not', 'to', 'be'].count('to) 2 >>>x = [[1, 2], 1, 1, [2, 1, [1, 2]]] >>>x.count(1) 2 >>>x.count([1, 2]) 1
extend
extend方法可以在列表的末尾一次追加一个序列中的多个值。
>>>a = [1, 2, 3] >>>a.extend([4, 5, 6]) >>>a [1, 2, 3, 4, 5, 6]
这个操作看起来很像连接操作,两者最主要区别在于: extend方法修改了被扩展的序列; 而原始的链接这不然,它会返回一个全新的序列
>>>a = [1, 2, 3] >>>b = [4, 5, 6] >>>a + b [1, 2, 3, 4, 5, 6] >>>a [1, 2, 3] >>>b [4, 5, 6] >>>a.extend(b) >>>a [1, 2, 3, 4, 5, 6]
使用
a.extend(b)等价于
a[len(a): ] = b,即使用分片赋值来实现相同的结果。
index
index方法用于从列表中找出某个值第一个匹配项的索引位置:
>>>knights = ['We', 'are', 'the', 'knights', 'who', 'say', 'ni'] >>>knights.index('who') 4 >>>knights.index('herring') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 'herring' is not in list
insert
insert方法用于将对象插入到列表中:
>>>numbers = [1, 2, 3, 5, 6, 7] >>>numbers.insert(3, 'four') >>>numbers [1, 2, 3, 'four', 5, 6, 7]
使用
numbers.insert(3, 'four')等价于
numbers[3: 3] = 'four',即用分片赋值来实现。
>>>numbers = [1, 2, 3, 6, 7] >>>numbers.insert(3,
pop
pop方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值
>>>x = [1, 2, 3] >>>x.pop() >>>3 >>>x [1, 2] >>>x.pop(0) 1 >>>x [2]
[注: pop方法是唯一一个既能修改列表有返回元素值(除了None)的列表]
pop方法可以实现出栈方法,而python没有入栈方法,但可以使用append方法来代替。pop方法和append方法的操作恰好相反。
>>>x = [1, 2, 3] >>>x.append(x.pop()) >>>x [1, 2, 3]
如果需要实现一个FIFO的队列,那么可以使用insert(0, ...)来代替append方法。或者,也可以继续使用append方法,但必须用pop(0)来代替pop()。更好的解决方案是使用collectin模块中deque对象)
remove
remove方法用于一处列表中某个值的第一个匹配项
>>>x = ['to', 'be', 'or', 'not', 'to', 'be'] >>>x.remove('be') >>>x ['to', 'or', 'not', 'to', 'be'] >>>x.remove('bee') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
remove是一个没有返回值的原位置改变方法。它修改了列表却没有返回值,这与pop方法相反。
reverse
reverse方法将列表中的元素反向存放:
>>>x = [1, 2, 3] >>>x.reverse() >>>x [3, 2, 1]
reverse方法改变了列表但不返回值(就像remove和sort)
sortsort方法用于在原位置对列表进行排序。
>>>x = [4, 6, 2, 1, 7, 9] >>>x.sort() >>>x [1, 2, 4, 6, 7, 9]
sort返回了x但返回了空值
>>>x = [4, 6, 2, 1, 7, 9] >>>y = x[: ] >>>y.sort() >>>x [4, 6, 2, 1, 7, 9] >>>y [1, 2, 4, 6, 7, 9]
再次强调调用x[: ]得到的是包含了x所有元素的分片,这是一种很有效的复制整个列表的方法。只是简单的吧x赋值给y是没用的,因为这样做就让x和y都指向同一个列表
>>>x = [4, 6, 2, 1, 7, 9] >>>y = x >>>y.sort() >>>x [1, 2, 4, 6, 7, 9] >>>y [1, 2, 4, 6, 7, 9]
另一种获得已排序的列表副本的方法是,使用sorted函数:
>>>x = [4, 6, 2, 1, 7, 9] >>>y = sorted(x) >>>x [4, 6, 2, 1, 7, 9] >>>y [1, 2, 4, 6, 7, 9]
sorted实际上可以用于任何序列,却总是返回一个列表:
>>>sorted('Python') ['P', 'h', 'n', 'o', 't', 'y']
高级排序
如果希望元素能按照特定的方式进行排序(而不是sort函数默认的方式,而根据python默认排序规则按升序排列元素),那么可以通过compare(x, y)的形式自定义比较函数。compare(x, y)函数会在x < y时返回复制, 在x > y时返回正值,如果x = y则返回0。定义好该函数之后,就可以提供给sort方法作为参数了。内建函数cmp提供了比较函数的默认实现方式:
>>>cmp(42, 32) 1 >>>cmp(99, 100) -1 >>>cmp(10, 10) 0 >>>numbers = [5, 2, 7, 9] >>>numbers.sort(cmp) >>>numbers [2, 5, 7, 9]
sort方法有另为两个可选参数--key和reverse。如果要使用它们,那么就要通过名字来指定。* 如果要根据元素的长度进行排序,那么可以使用len作为键函数:
>>>x = ['aaedvark', 'abalone', 'acme', 'add', 'aerate'] >>>x.sort(key=len) >>>x ['add', 'acme', 'aerate', 'abalone', 'aardvark'] * 另一个关键字参数reverse是简单的布尔值(True或False),用来指明 列表是否要进行反向排序: >>>x = [4, 6, 2, 1, 7, 9] >>>x.sort(reverse = True) >>>x [9, 7, 6, 4, 2, 1]
元组: 不可变序列
元组与序列一样,也是一种序列。唯一的不同是元组不能修改。(可以注意到,字符串也是如此。)创建元组的语法: 用逗号分隔一些值,那么就自动创建了元组。>>>1, 2, 3 (1, 2, 3)
元组也是(大部分时候)通过圆括号起来的:
>>>(1, 2, 3) (1, 2, 3)
空元组可以用没有包含内容的两个圆括号来表示:
>>>() ()
创建包含一个值的元组。实现方法有些奇特--必须加个逗号,即使只有一个值:
>>>42 42 >>>42, (42,) >>>(42,) (42,)
一个逗号能彻底地改变表达式的值:
>>>3 * (40 + 2) 126 >>>3 * (40 + 2, ) (42, 42, 42)
tuple函数
tuple函数的功能与list函数基本上是一样的: 以一个序列作为参数并把它转换为元组。>>>tuple([1, 2, 3]) (1, 2, 3) >>>tuple('abc') ['a', 'b', 'c'] >>>tuple((1, 2, 3)) (1, 2, 3)
基本元组操作
元组其实并不复杂--除了创建元组和访问元组元素之外,也没有太多其他擦做,可以参照其他类型的序列来实现:>>>x = 1, 2, 3 >>>x[1] 2 >>>x[0: 2] (1, 2)
那么, 意义何在
元素可以在映射(和集合的成员)中当作键使用--而列表则不行元组作为很多内建函数和方法的返回值存在,也就是说必须对元组进行处理。只要不尝试修改元组,那么,"处理"元组在绝大数情况下就是把它们当作列表进行操作
新函数
本章的新函数函数 & 描述\cmp(x, y) & 比较两个值\len(seq) & 返回序列的长度\list(seq) & 把序列转换成列表\max(args) & 返回序列或参数集合中的最大值\min(args) & 返回序列或参数集合中的最小值\reversed(seq) & 对序列进行反向迭代\sorted(seq) & 返回以排序的包含seq所有元素的列表\tuple(seq) & 把序列转换成组\相关文章推荐
- python-MySQL学习笔记-第二章-在特定数据库中创建表
- 流畅的python第二章序列构成的数组学习记录
- python核心编程学习(第二章)
- 《HeadFirst Python》第二章学习笔记
- 机器学习实战第二章-k近邻算法(包含一些python绘图基础)
- python学习第二章(序列)
- Python学习系列-----第二章 操作符与表达式
- Python学习笔记 --第二章
- 学习python的第三十九天-第二章 python必须知道的基础语法
- Python学习系列 ( 第二章):Python 的基础语法的使用
- python学习第二章(python基础编程第二版)
- python学习第二章变量和简单数据类型的部分课后练习自己尝试的代码
- 编程小白的第一本 python 入门书 学习笔记01 第二章 安装Python环境
- 菜狗的Python学习笔记 第二章 列表和元组
- 流畅的python学习笔记:第二章
- python学习笔记第二章
- Python学习之《python核心编程》 第二章课后答案
- 流程python学习笔记:第二章(2)
- PythonNLP学习进阶:第二章练习题(Python自然语言处理)
- 流程python学习笔记:第二章(1)