列表与字典在Python中都是其他对象的集合,因其支持嵌套类型,在使用时具有极高的灵活性,几乎可以在任何场合下表示与处理现实工程中的复杂数据结构。
列表
列表是Python中极具灵活特性的对象类型,与字符串不同的是列表可以包含任何Python核心对象类型,包括数字,字符串,甚至列表中还可以包含列表。列表与字符串一样,都是Python的有序序列类型,但是与字符串不同的是,列表是可变对象,可以对象本身进行修改。以下总结出Python列表的主要属性:
- 任意对象的有序集合
- 通过偏移读取列表内容
- 可变长度,异构以及任意嵌套:异构的含义是列表中的元素可以是不同数据对象类型。
- 属于可变序列的分类:可以在对象原处修改,任何修改都不会产生新的对象,而是在原来的内存空间上进行修改。
- 对象引用数组:当列表赋值给一个变量时,总是会将该列表的引用赋值给变量,而不是重新拷贝一个新的对象(除非有明确要求使用拷贝,拷贝产生新的对象)
列表基本操作
>>> l=[1,2,3,4,'a','b','c',[6,7,8,9,0]] #声明一个列表
>>> len(l) #求列表的长度,即元素的个数
8
>>> l[2] #用偏移量来访问指定位置元素
3
>>> l[7] #列表中可以嵌套列表
[6, 7, 8, 9, 0]
>>> l*2 #列表复制
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0]]
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0]]
>>> l.append('zz') #在列表尾端添加元素
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz']
>>> l.append('[zz]')
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]']
>>> l.append(['o','p','q']) # append方法是添加一个元素
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q']]
>>> l.extend([99,88,77]) # extend方法是,将参数列表合并成为一个列表
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q'], 99, 88, 77]
>>> l.sort() # 有不同的类型,字符类型与数字无法进行比较排序
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()
>>> l.index(1) # 找到为1的元素的偏移量
0
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q'], 99, 88, 77]
>>> l.index(99) # 返回99的元素偏移量
11
>>> l.count(99) # 元素99的个数
1
>>> l.pop() # 取出尾端元素,并从列表中删除
77
>>> l
[1, 2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q'], 99, 88]
>>> del l[0] # 删除偏移量为0的元素
>>> l
[2, 3, 4, 'a', 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q'], 99, 88]
>>> l.remove('a') #删除列表中为a的元素
>>> l
[2, 3, 4, 'b', 'c', [6, 7, 8, 9, 0], 'zz', '[zz]', ['o', 'p', 'q'], 99, 88]
>>>
列表迭代和解析
列表迭代就是用循环语句将列表中的每一个元素取出来执行一些特定的语句。
列表解析类似的,就是把序列中的每一个元素取出,执行特定的表达式从而生成新的列表的方式。列表解析的编码更简单,而且执行的速度更快。这与map函数有相似的作用。
>>> [ i**2 for i in range(5)]
[0, 1, 4, 9, 16]
>>> [ i**2 for i in range(5) if i % 2 ==0]
[0, 4, 16]
>>>
分片赋值
>>> l=[1,2,3,4]
>>> l[1:3]=[6,7,8,9] #分片赋值操作,实际上是将等号坐标的偏移量中的元素删除后,再加入等号右边的元素
>>> l #一次性替换掉整个分片的片段
[1, 6, 7, 8, 9, 4]
>>> l[1:4]=[] # 因为分片赋值是先删除,后插入元素的操作,用这种特性可以巧妙的删除一个分片片段
>>> l
[1, 9, 4]
>>>
字典
除了列表之外,Python中的字典也是很灵活的核心对象类型。与列表不同的是,字典是无序的映射集合(列表是有序的序列集合),字典主要有以下几个主要属性:
- 通过键而不是偏移量来读取:因字典是映射而且无序的集合,字典就无法通过偏移量来读取内容,只能采取键的形式
- 任意对象的无序集合:字典中的对象没有顺序。
- 可变长,异构,任意嵌套
- 属于可变映射类型
- 对象引用表(散列表):字典是支持键读取的引用表,从本质上讲,字典是作为散列表(支持快速检索的数据结构)来实现的,此外,Python采用最优化的散列算法来寻找键,因此搜索是很快速的。
字典基本操作
字典是在花括号中,以一系列的”键:值(key:value)”对形式写出的。
>>> zi={"name":"liximin","age":88,"address":'chengdu'}
>>> zi
{'address': 'chengdu', 'age': 88, 'name': 'liximin'}
>>> zi
{'address': 'chengdu', 'age': 88, 'name': 'liximin'}
>>> for i in zi : print(i) # 字典键值的迭代
...
address
age
name
>>> zi
{'address': 'chengdu', 'age': 88, 'name': 'liximin'}
>>> zi.update({'interest':{'music':'classic','balls':'football'}}) #字典合并
>>> zi
{'address': 'chengdu', 'interest': {'music': 'classic', 'balls': 'football'}, 'age': 88, 'name': 'liximin'}
>>> zi['interest']['balls'] # 字典嵌套多层键值引用
'football'
>>> zi['age']
88
>>> zi
{'address': 'chengdu', 'interest': {'music': 'classic', 'balls': 'football'}, 'age': 88, 'name': 'liximin'}
>>> zi.pop('age') # 字典取出元素
88
>>> zi
{'address': 'chengdu', 'interest': {'music': 'classic', 'balls': 'football'}, 'name': 'liximin'}
>>> zi.keys()
dict_keys(['address', 'interest', 'name'])
>>> len(zi) # 字典长度
3
>>> 'name' in zi # 判断字典中键值是否存在
True
>>> zi.get('aaa','ppp') # 如果没有找到相应的键值,则返回一个默认值
'ppp'
虽然字典是无序,但是如果要对他们进行排序,可以取出他们的键值列表再对列表进行排序,以按照顺序来取的字典中的值。
字典使用注意事项
- 序列运算对于字典来说无效。字典是映射机制,并不是序列。
- 对新键值赋值会添加字典元素。
- 键不一定总是字符串,字典中的键值总是唯一。
Python3.0中的字典变化
- 支持一种新的字典解析表达式,这与列表解析很类似
- 对于字典中的key,values,items方法返回的不再是列表,而是可迭代的视图
- 不再直接支持相对大小的比较——取而代之的是手动比较
- 不再有has_key方法——相反,使用in成员关系测试
字典解析
动态初始化一个字典的标准方式都是:将其键和值对应起来,并把它传递给dict函数。zip函数是在调用键和值的两个列表来构建字典的方式:
>>> list(zip(['a','b','c'],[1,2,3]))
[('a', 1), ('b', 2), ('c', 3)]
>>> dict(zip(['a','b','c'],[1,2,3])) #Python2.6和Python3.0中都可以使用
{'a': 1, 'c': 3, 'b': 2}
>>>
在python3.0中可以使用字典解析来构建一个新的字典:
>>> {i:i**2 for i in range(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>>
Python3中,字典有自己的迭代器,它会返回连续键。
>>> zi
{'address': 'chengdu', 'interest': {'music': 'classic', 'balls': 'football'}, 'name': 'jy'}
>>> for i in zi: print(i)
...
address
interest
name
>>>
字典键值排序
字典的key values items方法返回值都相比python2.6来说都有些不同,不会直接返回列表,再排序之前需要转化为列表:
>>> zi.items()
dict_items([('address', 'chengdu'), ('interest', {'music': 'classic', 'balls': 'football'}), ('name', 'jy')])
>>> zi.keys()
dict_keys(['address', 'interest', 'name'])
>>> zi.values()
dict_values(['chengdu', {'music': 'classic', 'balls': 'football'}, 'jy'])
>>> zi.keys().sort(0
...
KeyboardInterrupt
>>> zi.keys().sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'sort'
>>> zikey=list(zi.keys()) # 将keys函数返回的对象转化成为列表,然后对列表进行排序
>>> zikey.sort()
>>> zikey
['address', 'interest', 'name']
>>>
总结
字典与列表在python中是很常见的,使用起来非常灵活而且功能也非常强大,它们都是可变的,支持在原处修改对象本身。在使用时要分清可变性与不可变性。
列表是有序的序列类型,可以根据偏移量来访问列表内部的元素;字典是无序的映射类型,只能通过键值来访问,如果对字典中的元素顺序有要求时,可以对键值进行排序。字典的迭代器会返回自己的键值。