列表和元组
列表概览:
edward=['Edward Gumby',42]
john=['John Smith',50]
database=[edward,john]
print database
列表内的元素可以不是同一类型;列表也可以包含其他的列表。
通用序列操作:
所有序列类型都可以进行某些特定的操作。这些操作包括:索引(indexing)、分片(slicing)、加(adding)、乘(multiplying)以及检测某个元素是否属于序列的成员(成员资格)。除此之外,Python还有计算序列长度、找出最大元素和最小元素的内建函数。
索引:
序列中所有的元素都有编号——从0开始递增。这些元素可以通过编号分别访问:
greeting = 'Hello'
print greeting[0]
print greeting[-1]
输出为:
H
o
这就是索引。可以通过索引获取元素。所有序列都可以通过这种方式进行索引。使用负数索引时,Python会从右边,也就是从最后1个元素开始计数。最后1个元素的位置编号是-1(不是-0,因为那会和第一个元素重合)。
months = ['January','February','March','April','May','June','July','August',
'September','October','November','December']
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)
month_name = months[month_number-1]
ordinal = day+endings[day_number-1]
print month_name + ' ' + ordinal + ','+ year
输出:
Year:1995
Month(1~12):3
Day(1~31):30
March 30th,1995
分片:
与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围内的元素。分片通过冒号分隔开的两个索引来实现:
tag = '<a href="http://www.python.org">Python Web site</a>'
print tag[9:30]
print tag[32:-4]
输出:
http://www.python.org
Python Web site
number = [1,2,3,4,5,6,7,8,9,0]
print number[3:6]
print number[0:1]
输出:
[4, 5, 6]
[1]
简而言之,分片操作的实现需要提供两个索引的边界,第一个索引的元素是包含在分片内的,而第二个则不包括在分片内。
优雅的捷径:
假设需要访问最后的3个元素,那么当然可以进行显示的操作:
number = [1,2,3,4,5,6,7,8,9,10]
print number[7:10]
现在,索引10指向的是第11个元素,这个元素并不存在,却是在最后一个元素之后。
这样的做法也是可行的,但是,如果需要从列表的结尾开始计数呢?
number = [1,2,3,4,5,6,7,8,9,10]
print number[ -3:-1]
输出:
[8, 9]
看来并不能以这种方式访问最后的元素。那么使用索引0作为最后一步的下一步操作所使用的元素,结果有会怎样呢?
number = [1,2,3,4,5,6,7,8,9,10]
print number[ -3:0]
输出:
[]
所以,如果分片所得部分包括序列结尾的元素,那么,只需置空最后一个索引即可:
number = [1,2,3,4,5,6,7,8,9,10]
print number[ -3:]
输出:
[8, 9, 10]
这种方法同样适用于序列开始的元素:
number = [1,2,3,4,5,6,7,8,9,10]
print number[ :3]
输出:
[1, 2, 3]
实际上,如果需要复制整个序列,可以将两个索引都置空:
number = [1,2,3,4,5,6,7,8,9,10]
print number[ :]
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# _*_ coding:utf8 _*_
#u'对http://www.something.com形式的URL进行分割'
url = raw_input('Please enter the URL:')
domain = url[11:-4]
print 'Domain name:' + domain
输出:
Please enter the URL:http://www.python.org
Domain name:python
更大的进步
进行分片的时候,分片的开始和结束点需要进行指定(不管是直接还是间接)。而另一个参数——步长,——通常都是隐式设置。在普通的分片中,步长是1——分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。
number = [1,2,3,4,5,6,7,8,9,10]
print number[0:10:1]
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
在这个例子中,分片包含了另外一个数字。没错,这就是步长的显式设置。如果步长被设置为比一大的数,那么就会跳过某些元素。例如,步长为2的分片包括的是从开始到结束每隔一个元素。
number = [1,2,3,4,5,6,7,8,9,10]
print number[0:10:2]
print number[3:6:3]
print number[::4]
print number[8:3:-1]
print number[10:0:-2]
print number[0:10:-2]
print number[::-2]
print number[5::-2]
print number[:5:-2]
[1, 3, 5, 7, 9]
[4]
[1, 5, 9]
[9, 8, 7, 6, 5]
[10, 8, 6, 4, 2]
[]
[10, 8, 6, 4, 2]
[6, 4, 2]
[10, 8]
这里要得到正确的分片结果需要动些脑筋。开始点的元素(最左边的元素)包括在结果之中,而结束点的元素则不在分片内。当使用一个负数作为步长时,必须让开始点(开始索引)大于结束点。在没有明确指定开始点和结束点的时候,正负数的使用可能会带来一些混淆。不过这种情况下Python会进行正确的操作:对于一个正数步长,Python会从序列的头部开始向右提取元素,直到最后一个元素;而对于负数步长,则是从序列的尾部开始向左提取元素,直到第一个元素。
序列相加:
通过使用加运算符可以进行序列的连接操作:
print [1,2,3]+[4,5,6]
print 'hello ' + 'world!'
输出:
[1, 2, 3, 4, 5, 6]
hello world!
print [1,2,3]+'hello '
输出:
Traceback (most recent call last):
File "/tmp/untitled/list.py", line 1, in <module>
print [1,2,3]+'hello '
TypeError: can only concatenate list (not "str") to list
乘法:
print 'Hello!'*5
输出:
Hello!Hello!Hello!Hello!Hello!
[42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
None、空列表和初始化
# _*_coding:utf8_*_
#以正确的宽度在居中的“盒子”中内打印一个句子
sentence = raw_input("Sentence:")
screen_width=80
text_width=len(sentence)
box_width=text_width*6
left_margin=(screen_width-box_width)/2
#整数除法运算符(//)
print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'
print ' ' * (left_margin+2 * text_width)+ '|' + ' ' *text_width + '|'
print ' ' * (left_margin+2 * text_width)+ '|' + sentence + '|'
print ' ' * (left_margin+2 * text_width) + '|' + ' ' *text_width + '|'
print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'
Sentence:1234567890
+----------------------------------------------------------+
| |
|1234567890|
| |
+----------------------------------------------------------+
成员资格:
in 运算符:
str = 'rw'
print 'w' in str
print 'x' in str
users = ['mlh','foo','bar']
print raw_input('Enter your user name:') in users
输出:
True
False
Enter your user name:mlh
True
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'
else:
print 'False'
输出:
User name:albert
PIN code:1234
Access granted
长度、最小值和最大值:
内建函数len、min和max非常有用。
len函数返回序列中所包含元素的数量;
min函数和max函数则分别返回序列中最小的和最大的元素。
numbers = [100, 34, 678]
print len(numbers)
print max(numbers)
print min(numbers)
print max(2,3)
print min(9,3,2,5)
输出:
3
678
34
3
2
列表:Python的“苦力”
list函数:
因为字符串不能像列表一样被修改,所以有时根据字符串创建列表会很有用。list函数可以实现这个操作:
print list('helle')
输出:
['h', 'e', 'l', 'l', 'e']
基本的列表操作:
改变列表:元素赋值
x = [1,1,1]
x[1] = 2
print x
输出:
[1, 2, 1]
删除元素
del函数:
names = ['Alice','Beth','Cecil','Dee-Dee','Earl']
del names[2]
print names
输出:
['Alice', 'Beth', 'Dee-Dee', 'Earl']
分片赋值
name = list('Perl')
print name
name[2:] = list('ar')
print name
name[1:] = list('ython')
print name
numbers = [1,5]
numbers[1:1] = [2,3,4]
print numbers
numbers[1:4] = []
print numbers
输出:
['P', 'e', 'r', 'l']
['P', 'e', 'a', 'r']
['P', 'y', 't', 'h', 'o', 'n']
[1, 2, 3, 4, 5]
[1, 5]
列表方法:
对象.方法.(参数)
1、append
append方法用于在列表末尾追加新的对象:
lst = [1,2,3]
lst.append(4)
print lst
输出:
[1, 2, 3, 4]
2、count
count方法统计某个元素在列表中出现的次数:
list = ['to','be','or','not','to','be']
print list.count('to')
x = [[1,2],1,1,[2,1,[1,2]]]
print x.count(1)
print x.count([1,2])
输出:
2
2
1
3、extend
extend方法可以在列表的末尾一次性追加另一个序列中的多个值:
a = [1,2,3]
b = [4,5,6]
a.extend(b)
print a
输出:
[1, 2, 3, 4, 5, 6]
同样也可以用分片赋值的方法实现。
4、index
index方法用于从列表中找出某个值第一个匹配项的索引位置:
knight = ['We','are','the','knight','who','say','ni']
print knight.index('who')
5、insert
insert方法用于将对象插入到列表中:
numbers = [1,2,3,5,6,7]
numbers.insert(3,'four')
print numbers
6、pop
pop方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值:
x = [1,2,3]
print x.pop()
x.pop(0)
print x
7、remove
remove方法用于移除列表中某个值的第一个匹配项:
x=['to','be','or','not','to','be']
x.remove('be')
print x
8、reverse
reverse方法将列表中的元素反向存放:
x = [1,2,3,4]
x.reverse()
print x
9、sort
x = [4,6,2,1,7,9]
x.sort()
print x
获取已排序的列表副本:
x = [4,6,2,1,7,9]
y = sorted(x)
print x
print y
输出:
[4, 6, 2, 1, 7, 9]
[1, 2, 4, 6, 7, 9]
10、高级排序
print cmp(42,32)
print cmp(90,100)
print cmp(10,10)
numbers = [5,2,9,7]
numbers.sort(cmp)
print numbers
输出:
1
-1
0
[2, 5, 7, 9]
比较长度后排序:
x = ['aardvark','abalone','acme','add','aerate']
x.sort(key = len)
print x
输出:
['add', 'acme', 'aerate', 'abalone', 'aardvark']
x = [4,6,2,1,7,9]
x.sort(reverse=True)
print x
输出:
[9, 7, 6, 4, 2, 1]
元组:不可变序列
tuple函数
tuple函数的功能和list函数的功能基本上是一样的:以一个序列作为参数并把他转换为元组。如果参数本身就是元组,那么该参数就会被原样返回:
print tuple('abc')
print tuple([1,2,3])
print tuple((1,2,3))
输出:
('a', 'b', 'c')
(1, 2, 3)
(1, 2, 3)
基本元组操作
x = 1,2,3
print x[1]
print x[0:2]
输出:
2
(1, 2)
本章的新函数
cmp(x,y) | 比较两个值 |
len(seq) | 返回序列的长度 |
list(seq) | 把序列转换为列表 |
max(args) | 返回序列或者参数集合中的最大值 |
min(args) | 返回序列或者参数集合中的最小值 |
reversed(seq) | 对序列进行反向迭代 |
sorted(seq) | 返回一排序的包含seq所有元素的列表 |
tuple(seq) | 把序列转换成元组 |