Python基本数据结构
纸上得来终觉浅,绝知此事要躬行。
数据结构,是计算机存储、组织数据的方式。而序列是 Python 中最基本的数据结构,序列的每一个元素都会被分配一个序号,也就是元素的位置,叫做索引。
- 内置的序列类型
- List 列表
- Tuple 元组
- range 函数
- Str 文本序列
- Binary 二进制(bytes、bytearray、memoryview)
- Set 和 frozenset 集合
- Dict 字典
1. 列表
常用于存储可变类型元素
- append
In [1]: firends = [] In [2]: firends.append('MissSun') In [3]: firends Out[3]: ['MissSun']
- extend
In [4]: firends.extend(['Escape', 'Tom']) In [5]: firends Out[5]: ['MissSun', 'Escape', 'Tom']
- insert
In [20]: firends.insert(1, 'Wang') In [21]: firends Out[21]: ['MrSun', 'Wang', 'Bob', 'Lucy', 'Jetty']
- len
In [21]: firends Out[21]: ['MrSun', 'Wang', 'Bob', 'Lucy', 'Jetty'] In [22]: len(firends) Out[22]: 5
- 分片
# 分片使用 In [6]: firends Out[6]: ['MissSun', 'Escape', 'Tom'] In [7]: firends[2] Out[7]: 'Tom' In [8]: firends[-1] Out[8]: 'Tom' In [9]: firends[1:10] Out[9]: ['Escape', 'Tom'] In [10]: firends[1:] Out[10]: ['Escape', 'Tom'] In [11]: firends[:1] Out[11]: ['MissSun']
# 分片步长 In [12]: [1, 2, 3, 4, 5][:] Out[12]: [1, 2, 3, 4, 5] In [13]: [1, 2, 3, 4, 5][0:4:2] Out[13]: [1, 3] In [14]: [1, 2, 3, 4, 5][::-1] Out[14]: [5, 4, 3, 2, 1]
- 修改元素
In [15]: firends Out[15]: ['MissSun', 'Escape', 'Tom'] In [16]: firends[0] = 'MrSun' In [17]: firends Out[17]: ['MrSun', 'Escape', 'Tom'] In [18]: firends[1:3] = ['Bob', 'Lucy', 'Jetty'] In [19]: firends Out[19]: ['MrSun', 'Bob', 'Lucy', 'Jetty']
- 删除元素
In [21]: firends.clear() In [22]: firends Out[22]: [] In [23]: firends Out[23]: ['MrSun', 'Wang', 'Bob', 'Lucy', 'Jetty'] # 知道元素对应的索引 In [24]: del firends[0] In [25]: firends Out[25]: ['Wang', 'Bob', 'Lucy', 'Jetty'] # 从列表末尾删除元素 In [26]: firends.pop() Out[26]: 'Jetty' In [27]: firends Out[27]: ['Wang', 'Bob', 'Lucy'] # 从列表指定位置删除元素 In [28]: firends.pop(1) Out[28]: 'Bob' In [29]: firends Out[29]: ['Wang', 'Lucy'] # 不知道元素对应的索引 In [30]: firends.remove('Lucy') In [31]: firends Out[31]: ['Wang']
- 搜索元素
In [32]: l = [1, 2, 1, 3] In [33]: l.index(1) Out[33]: 0 In [34]: l.index(1, 1) Out[34]: 2 In [35]: l.index(6) 抛出ValueError: 6 is not in list In [36]: 3 in l Out[36]: True In [37]: 6 in l Out[37]: False In [38]: l.count(1) Out[38]: 2
- 排序元素
# 只排序不修改元素 In [41]: l Out[41]: [1, 2, 1, 3] In [42]: sorted(l) Out[42]: [1, 1, 2, 3] In [43]: sorted(l, reverse=True) Out[43]: [3, 2, 1, 1] In [44]: l Out[44]: [1, 2, 1, 3]
# 排序且修改元素 In [44]: l Out[44]: [1, 2, 1, 3] In [45]: l.sort() In [46]: l Out[46]: [1, 1, 2, 3]
# 排序且修改元素 In [47]: l Out[47]: [1, 1, 2, 3] In [48]: list(reversed(l)) Out[48]: [3, 2, 1, 1] In [49]: l Out[49]: [1, 1, 2, 3] In [50]: l.reverse() In [51]: l Out[51]: [3, 2, 1, 1]
# sorted函数的特殊的使用方式 In [1]: strs = ['ccc', 'aaaa', 'd', 'bb'] In [2]: print(sorted(strs, key=len)) ['d', 'bb', 'ccc', 'aaaa'] In [3]: print(sorted(strs, key=str.lower)) ['aaaa', 'bb', 'ccc', 'd']
# sorted函数的特殊的使用方式 In [4]: strs = ['xc', 'zb', 'yd' ,'wa'] In [5]: def MyFn(s): : return s[-1] In [6]: print(sorted(strs, key=MyFn)) ['wa', 'zb', 'xc', 'yd']
2. 元组
常用于存储不可变的元素
- 类型转换
In [1]: tuple([1, 2]) Out[1]: (1, 2) In [2]: list((1, 2)) Out[2]: [1, 2]
- 执行效率
[[email protected] ~]$ python -m timeit '["Escape", "MissSun", "Bob", "Lucy"]' 10000000 loops, best of 3: 0.064 usec per loop [[email protected] ~]$ python -m timeit '("Escape", "MissSun", "Bob", "Lucy")' 100000000 loops, best of 3: 0.0147 usec per loop
- 定义方式
In [5]: tup = (1) In [6]: tup is 1 Out[6]: True In [7]: type(tup) Out[7]: int In [8]: tup = (1,) In [9]: tup is 1 Out[9]: False In [10]: type(tup) Out[10]: tuple
- 使用技巧
In [1]: tup = (1, 2, 'a', 1) In [2]: tup.index(1) Out[2]: 0 In [3]: tup.index(1, 1) Out[3]: 3 In [4]: tup.index(1, 1, 4) Out[4]: 3 In [5]: tup.count('a') Out[5]: 1
- 赋值谜题
In [6]: tup = (1, 2, [3, 4]) In [7]: tup[2] += [5, 6] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-7-2c0f8d13e641> in <module>() ----> 1 tup[2] += [5, 6] TypeError: 'tuple' object does not support item assignment In [8]: tup Out[8]: (1, 2, [3, 4, 5, 6]) # 虽然报错但操作却成功了,这里因为“+=”操作分为两步,即第一步对元组中列表进行添加成功了, # 但是后面的赋值为元组操作失败,所以我们能够看到下面的结果也不足为奇了。
3. 字典
常用于存储需要明辨的键值对元素
- 使用方式
# 定义方式 In [1]: D = {} In [2]: D[1] = 'a' In [3]: D['a'] = 1 In [4]: D Out[4]: {1: 'a', 'a': 1}
# 元素获取 In [13]: D = {'a':1} In [14]: D.get('a') Out[14]: 1 In [15]: D.get('b') In [16]: D.get('b', 2) Out[16]: 2
# 元素更新 In [20]: D.update(a=1, b=2, c=3) In [21]: D Out[21]: {'a': 1, 'b': 2, 'c': 3} In [22]: 'a' in D Out[22]: True In [23]: del D['a'] In [24]: 'a' in D Out[24]: False
# 获取键值对 In [31]: D Out[31]: {'a': 1, 'b': 2, 'c': 3} In [32]: D.keys() Out[32]: dict_keys(['a', 'b', 'c']) In [33]: D.values() Out[33]: dict_values([1, 2, 3]) In [34]: D.items() Out[34]: dict_items([('a', 1), ('b', 2), ('c', 3)]) # 在Python2中会看到一些带iter的方法,这是因为在Python2.7之前的版本获取字典中的键值对会 # 一次性全部取出,导致效率和内存消耗很大,所以才会出现iter的这种形式,类似于xrange一样, # 但在Python3中已经正式取消了。 >>> D = dict(a=1, c=3) >>> D.iterkeys() <dictionary-keyiterator object at 0x108944cd1> >>> list(D.iterkeys()) ['a', 'c'] >>> list(D.itervalues()) [1, 3] >>> list(D.iteritems()) [('a', 1), ('c', 2)]
- 键值存储
In [5]: D = {} # 存储商品是,需要特意进行分割和拼接 In [6]: D['{}_{}'.format('a', 'c')] = 'T' In [7]: D Out[7]: {'a_c': 'T'} # 但是这样需要查询两次,效率不高 In [8]: D = { 'a': {'c': 'T', 'd': 'N'} } In [9]: D['a']['c'] Out[9]: 'T' # 使用元组就能很好地结果这个问题 In [10]: D[('a', 'c')] = 'T' In [11]: D[('a', 'c')] Out[11]: 'T'
- 字典顺序
# 在Python2中字典是没有顺序的,而Python3中是顺序的 >>> D = {'a':1, 'b':2 , 'c':3} >>> D {'a': 1, 'c': 3, 'b': 2} # 需要借助其他方法进行顺序化 >>> from collections import OrderedDict >>> D = OrderedDict() >>> D = {'a':1, 'b':2 , 'c':3} >>> D {'a': 1, 'b': 2, 'c': 3}
4. 集合
集合中存储的内容不会重复的
- 使用方式
In [1]: {1, 2, 3, 1, 1} Out[1]: {1, 2, 3} In [2]: s = set() In [3]: s Out[3]: set()
- 常见方法
# 添加元素 # 重复元素会被替换过滤掉 In [4]: s = set() In [5]: s.add(1) In [6]: s.add(1) In [7]: s Out[7]: {1} In [9]: s.update([2, 3])
# 删除元素 # 因为集合是无序的,所以无法使用pop方法删除元素 In [10]: s Out[10]: {1, 2, 3} In [11]: s.remove(3) In [12]: s Out[12]: {1, 2} In [13]: s.remove(3) --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-13-b06e0f5ff900> in <module>() ----> 1 s.remove(3) KeyError: 3 In [14]: s.discard(3)
- 类型转换
# 注意转换是不考虑顺序的 In [2]: set([1, 3, 2, 1]) Out[2]: {1, 2, 3} In [3]: list({1, 3, 2, 1}) Out[3]: [1, 2, 3]
- 集合关系
In [15]: set([1]).issubset(set([1, 2])) Out[15]: True In [16]: set([1]).issuperset(set([1, 2])) Out[16]: False In [17]: set([1, 2]).issuperset(set([1])) Out[17]: True
- 集合操作
In [18]: s1 = set([1, 2, 3]) In [19]: s2 = set([3, 4, 1]) # 交集 In [20]: s1 & s2 Out[20]: {1, 3} # 并集 In [21]: s1 | s2 Out[21]: {1, 2, 3, 4} # 差集 In [22]: s1 - s2 Out[22]: {2} In [23]: s2 - s1 Out[23]: {4}
- 不变集合
# 不能够改变集合的元素 In [24]: fs = frozenset(lst) In [25]: fs Out[25]: frozenset({'E', 'a', 'c', 'e', 'p', 's'}) In [26]: fs.add('a') --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-26-519afcaebdd3> in <module>() ----> 1 fs.add('a') AttributeError: 'frozenset' object has no attribute 'add'