第02章: 列表和数组
------
在Python中最基本的数据结构是序列,每个元素分配一个序号,即元素的序号,也即索引。注意,需要从0开始,第一位0,第二位为1,依次类推. Python包括: 字符串,列表,元祖,字典 这四种常用数据结构,或者说四种序列,其中元祖为不可变序列.
列表和元祖的主要区别
- 列表可变,而元祖不可变 >>>list1 = ['Tom',40]
- 所以元祖: 主要用于存储不变的数据 >>>
>>> tuple1 = (130,131,132,133,134)
>>> tuple1[0]=135
Traceback (most recent call last):
File "<pyshell#199>", line 1, in <module>
tuple1[0]=135
TypeError: 'tuple' object does not support item assignment
>>> list = ['Tom',40]
>>> list
['Tom', 40]
>>> list[0]='Jerry'
>>> list
['Jerry', 40]
再比如:要建个记录姓名,和年龄的元祖,可以这样:
>>> edward = ['Edward Gumby',40]
>>> john = ['John Smith',50]
>>> database = [edward,john]
>>> database
[['Edward Gumby', 40], ['John Smith', 50]]
------
通用序列可做的操作:
- 索引
- 切片
- 增加元素
- 删除元素
- 更新元素
- 查找元素(检查某个元素是否是序列中的一员)
- 序列长度
- 最大值
- 最小值
- 其他内建函数
------
索引
>>> greeting = 'Hello World!'
>>> greeting[0]
'H'
>>> greeting[-1]
'!'
如果只对年份的第四位感兴趣,可以这样:
>>> fouth = raw_input('Year: ')[3]
Year: 2008
>>> fouth
'8'
<span style="font-size:18px;">#Filename: showmonth.py
months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
year = raw_input('Year: ')
month = raw_input('Month(1-12): ')
day = raw_input('Day(1-31): ')
endings = ['st','nd','rd'] + 17*['th'] + \
['st','nd','rd'] + 07*['th'] + \
['st']
month_number = int(month)
day_number = int(day)
month_name = months[month_number-1]
ordinal = day + endings[day_number]
print month_name[:3] + ' ' + ordinal + ', ' + year
# 输出结果
D:\>python showmonth.py
Year: 2014
Month(1-12): 09
Day(1-31): 13
Sep 13th, 2014
</span>
------
切片
>>> 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[7:10]
[8, 9, 10]
#或者直接到:表示后面的
>>> numbers[7:]
[8, 9, 10]
#[:]或者[::]表示所有的
>>> numbers[-3:]
[8, 9, 10]
#倒序输出,步幅为-1,即从右到左
>>> numbers[-1:-4:-1]
[10, 9, 8]
#输出开始的三位
>>> 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]
例子:取http://www.something.com中的域名:
url = raw_input('Enter Url Here:')
Enter Url Here:http://www.sohu.com
print "Domain is:" + url[11:-4]
Domain is:sohu
------
更大步长
>>> numbers[0:10:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> numbers[0:10:2]
[1, 3, 5, 7, 9]
>>> numbers[::4]
[1, 5, 9]
>>> numbers[8:3:-1]
[9, 8, 7, 6, 5]
>>> numbers[10:0:-2]
[10, 8, 6, 4, 2]
>>> numbers[0:10:-2]
[]
>>> numbers[::-2]
[10, 8, 6, 4, 2]
>>> numbers[5::-2]
[6, 4, 2]
#序列相加,只有相同类型的才可以
>>> [1,2]+[3,4]
[1, 2, 3, 4]
>>> 'Hello,'+'World!'
'Hello,World!'
>>> [1,2]+'Hello'
Traceback (most recent call last):
File "<pyshell#253>", line 1, in <module>
[1,2]+'Hello'
TypeError: can only concatenate list (not "str") to list
------
乘法
#列表倍乘
>>> [0]*10
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
#字符串倍乘
>>> 'python'*5
'pythonpythonpythonpythonpython'
#序列初始化
>>> seq = [None]*10
>>> seq
[None, None, None, None, None, None, None, None, None, None]
字符串乘法例子
#以正确的宽度在居中的“盒子”内打印一个句子
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+2) + ' |'
print ' '*left_margin + '| ' + sentence + ' '*2 + ' |'
print ' '*left_margin + '| ' +' '*(text_width+2) + ' |'
print ' '*left_margin + '+' +'-'*(box_width-2) + '+'
print
D:\Work\Python>python showmonth.py
Sentence:I Love Python
+-----------------+
| |
| I Love Python |
| |
+-----------------+
------
成员资格:
用in运算符号判断成员资格,在则为True,不在则为假:
>>> permissions='rw'
>>> 'w' in permissions
True
>>> 'x' in permissions
False
users=['root','test','guest']
print raw_input('Name:') in users
D:\>python showmonth.py
Name:root
True
>>> subject = '$$$ Get Rich Now! $$$'
>>> '$$$' in subject
True
database=[
['root','1234'],
['test','5678'],
['book','9012']
]
user = raw_input('Enter user: ')
puid = raw_input('Enter puid: ')
if [user,puid] in database:
print 'Access Granted.'
else:
print 'User or Pid not correct.'
------
长度,最大值,最小值
>>> n = [78,23,64]
>>> len(n);max(n);min(n)
3
78
23
可对多值进行比较
>>> min(9,3,2,5) ; max(9,3,2,5)
2
9
------
list函数
#将字符串转为由单个字符的列表
>>> list('hello')
['h', 'e', 'l', 'l', 'o']
#将由字符组成的列表转成字符串
>>> list1=['d','a','y']
>>> ''.join(list1)
'day'
------
基本操作
#更新元素,赋值
>>> x = [0,1,2]
>>> x[0]=8
>>> x
[8, 1, 2]
Note:不能为一个不存在的索引的赋值,比如像上面的例子
>>> x[3]=3
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
x[3]=3
IndexError: list assignment index out of range
#删除元素
>>> names=['Jerry','John','Jack','Alice']
>>> del names[3]
>>> names
['Jerry', 'John', 'Jack']
Note: del可以删除定义的各个变量,函数等
>>> s = '1234'
>>> def sum1(x,y):
return x+y
>>> sum1(1,2)
3
>>> del s; del sum1
>>> s
Traceback (most recent call last):
File "<pyshell#51>", line 1, in <module>
s
NameError: name 's' is not defined
>>> sum1(1,2)
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
sum1(1,2)
NameError: name 'sum1' is not defined
分片赋值
#同长度赋值
>>> name=list('Perl')
>>> name
['P', 'e', 'r', 'l']
>>> name[2:]='ar'
>>> name
['P', 'e', 'a', 'r']
#不同长度赋值
>>> name=list('Perl')
>>> name
['P', 'e', 'r', 'l']
>>> name[1:]='ython'
>>> name
['P', 'y', 't', 'h', 'o', 'n']
#分片可以在不更改原值的情况下,插入新元素
>>> number = [1,5]
>>> number[1:1]=[2,3,4]
>>> number
[1, 2, 3, 4, 5]
#分片可以插入,也可以删除,相当于插入了'空片'
>>> number = [1,2,3,4,5]
>>> number[1:4]=[]
>>> number
[1, 5]
等价于 del number[1:4]
------
列表方法
append: 末尾添加
>>> num = [1,2,3]
>>> num.append(4)
>>> num
[1, 2, 3, 4]
count: 计算列表中元素出现的次数
>>> ['to','re','be','hi','to'].count('to')
2
>>> list1 = [[1,2],1,1,2,2,[2,1]]
>>> list1.count(1)
2
>>> list1.count([1,2])
1
extend: 列表后面添加新列表
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
extend与列表相加的区别: extend改变了被添加列表的值,而直接相加则没有
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a + b
[1, 2, 3, 4, 5, 6]
>>> a
[1, 2, 3]
当然,也可以用切片的方式插入,但从程序可读性不如extend函数
>>> a = [1,2,3]
>>> a[len(a):] = [4,5,6]
>>> a
[1, 2, 3, 4, 5, 6]
index:从序列中找出第一个匹配项的索引值
>>> list1=['I','love','python','i','love','perl']
>>> list1.index('love')
1
>>> list1[1]
'love'
#如果没有的话,则会返回不在列的异常
>>> list1.index('java')
Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
list1.index('java')
ValueError: 'java' is not in list
insert:在列表的特定位置插入项
>>> numbers = [1,2,3,5,6]
>>> numbers.insert(3,'four')
>>> numbers
[1, 2, 3, 'four', 5, 6]
#当然也可以用切片的方式来完成,但可读性不如insert
>>> numbers = [1,2,3,5,6]
>>> numbers[3:3]=['four']
>>> numbers
[1, 2, 3, 'four', 5, 6]
pop: 移除列表中的元素,默认的话是最后一位
Note:
- pop是即能修改元素又能返回列表值(None除外)的函数
- 可以append(pop(0))来实现FIFO功能
- 也可以用insert(0...)配合pop来实现FIFO或者collection中的deque对象
>>> x = [1,2,3]
>>> x.pop()
3
>>> x
[1, 2]
>>> x.pop(0)
1
>>> x
[2]
pop可以实现栈(FIFO:先进先出,入栈(push)、出栈(pop))
pop 保持不变,push等价于append
>>> x = [1,2,3]
>>> x.append(x.pop())
>>> x
[1, 2, 3]
remove: 移除匹配中第一个元素值
Note:和pop相对,都是操作第一个匹配值,但remove没有返回项
>>> x =['to','be','or','not','to','be']
>>> x.remove('be')
>>> x
['to', 'or', 'not', 'to', 'be']
reverse: 将列表中的值反向存放
>>> x = [1,2,3]
>>> x.reverse()
>>> x
[3, 2, 1]
Note:如果要对一个列表实现反向迭代,可以用reversed,但该函数不返回具体值,
只是个迭代(iterator),但可以用list()函数列出来.
<pre name="code" class="python"><listreverseiterator object at 0x00000000030028D0>
>>> x = [1,2,3]>>> list(reversed(x))[3, 2, 1]
sort: 在原位置对列表进行排序
#原先的列表会改变
>>> x = [3,1,4,2,5]
>>> x.sort()
>>> x
[1, 2, 3, 4, 5]
#注意下面是错误,y返回是个空值
>>> x = [3,1,4,2,5]
>>> y = x.sort()
>>> y
None
#正确操作是先对x做个拷贝,再对y进行操作
>>> x = [3,1,4,2,5]
>>> y = x[::]
>>> y.sort()
>>> y
[1, 2, 3, 4, 5]
另外一个对列表排序的方法是sorted()
Note:如果打算同时做sort,reverse操作,x.sort().reverse()是错误,sorted(x).reverse()则是正确的.
>>> x = [3,1,4,2,5]
>>> y = sorted(x)
>>> x
[3, 1, 4, 2, 5]
>>> y
[1, 2, 3, 4, 5]
Note:
sorted可以对任意序列进行操作,返回一个序列值
>>> s = 'book'
>>> sorted(s)
['b', 'k', 'o', 'o']
高级排序:
cmp,key,reverse结合使用
#cmp+sort
#sort 排序是按照默认升序排列方式,如果要实现特定的排序方式,可以cmp,结合sort来用
>>> x = [5,2,7,4]
>>> x.sort(cmp)
>>> x
[2, 4, 5, 7]
#key为具体键值,比如说长度,具体key键值,可以参考文档
>>> x
['Welcome', 'to', 'Chengdu', '!']
>>> x.sort(key=len)
>>> x
['!', 'to', 'Welcome', 'Chengdu']
#reverse,True或False来确定是否需要反转
>>> x = [9,7,1,3,2]
>>> x.sort(reverse=True)
>>> x
[9, 7, 3, 2, 1]
------
元祖: 和字符串一样,元祖是不可变的,基本操作同列表.
Note:
- print函数就是结合元祖来使用
- 用于存储永恒不变的值,如身份证号码,日期等
>>> x = [4,3,1,2]
>>> x[0]
4
>>> x.pop()
2
>>> x[1:]
[3, 1]
下面是创建元祖方式:
#任何元素直接加逗号
>>> 1,2,3
(1, 2, 3)
>>> 'hello','world'
('hello', 'world')
#加()
>>> (1,2,3)
(1, 2, 3)
#建空元祖
>>> ()
()
#建一个元素的元祖
>>> 1,
(1,)
>>> (1,)
(1,)
例子: 前者是值,后者是元祖,返回对象不同
>>> 3*(9+1)
30
>>> 3*(9+1,)
(10, 10, 10)
tuple: 将序列转变为元祖
>>> l1=[1,2,3,4]
>>> s1='python'
>>> t1=(1,2,3)
>>> tuple(l1);tuple(s1);tuple(t1)
(1, 2, 3, 4)
('p', 'y', 't', 'h', 'o', 'n')
(1, 2, 3)
------
本章新函数
cmp(x,y) 比较两个值
len(seq) 返回序列的长度
list(seq) 将序列转为列表
max(args) 返回序列或者参数集合的最大值
mix(args) 返回序列或者参数结合的最小值
reversed(seq) 对序列进行反向迭代
tuple(seq) 把序列转换成元祖
------