您的位置:首页 > 编程语言 > Python开发

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) & 把序列转换成组\
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: