Python 的数据结构

1,元组

元组是一个固定长度,不可改变的Python序列对象。
创建元组的最简单方式,是用逗号分隔一列值:

In [1]: tup = 4, 5, 6

In [2]: tup
Out[2]: (4, 5, 6)

当用复杂的表达式定义元组时,最好,比如这样

In [3]: nested_tup = (4, 5, 6), (7, 8)

In [4]: nested_tup
Out[4]: ((4, 5, 6), (7, 8))

用tuple可以将任意序列或迭代器转化为元组

In [5]: tuple([4, 0, 2])
Out[5]: (4, 0, 2)

In [6]: tup = tuple('string')

In [7]: tup
Out[7]: ('s', 't', 'r', 'i', 'n', 'g')

可以用方括号访问元组中的内容,序列以0开头

In [8]: tup[0]
Out[8]: 's'

元组中的对象不能进行改变否则将报错

In [9]: tup = tuple(['foo', [1, 2], True])

In [10]: tup[2] = False
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-c7308343b841> in <module>()
----> 1 tup[2] = False
TypeError: 'tuple' object does not support item assignment

但是如果元组中某个对象是可变对象,比如列表,可以对这个对象在原位进行修改

In [11]: tup[1].append(3)

In [12]: tup
Out[12]: ('foo', [1, 2, 3], True)

元组可以用“+”号进行组合

In [13]: (4, None, 'foo') + (6, 0) + ('bar',)
Out[13]: (4, None, 'foo', 6, 0, 'bar')

元组可以乘以数值,会把元组中的对象进行复制就像列表一样

1.2、拆分元组

相对于其他语言,python可以智能的把元组赋值给类似元组的变量(注意元组中有多少个对象,原则上就需要有多少个变量)

In [15]: tup = (4, 5, 6)

In [16]: a, b, c = tup

In [17]: b
Out[17]: 5

即使含有元组的元组也会被拆分:

In [18]: tup = 4, 5, (6, 7)

In [19]: a, b, (c, d) = tup

In [20]: d
Out[20]: 7

变量也可以是一个元组,例如这样也行

In [18]: tup = 4, 5, (6, 7)

In [19]: a, b, c = tup

In [20]: c
Out[20]: (6,7)

使用这个功能,你可以很容易地替换变量的名字,其它语言可能是这样:

tmp = a
a = b
b = tmp

但是在 Python 中,替换可以这样做:

In [21]: a, b = 1, 2

In [22]: a
Out[22]: 1

In [23]: b
Out[23]: 2

In [24]: b, a = a, b

In [25]: a
Out[25]: 2

In [26]: b
Out[26]: 1

也可以只把元组开头的几个对象赋值给变量,其他的都不要例如这样

In [29]: values = 1, 2, 3, 4, 5
#只要元组的前两个对象,剩余的对象打包给rest,注意符号"*"
#rest的部分是想要舍弃的部分,rest的名字不重要。作为惯用写法,许多 Python 程序员会将不需要的变量使用下划线:
In [33]: a, 
In [30]: a, b, *rest = values

In [31]: a, b
Out[31]: (1, 2)

In [32]: rest
Out[32]: [3, 4, 5]

因为元组的大小和内容不能修改,所以针对元组的实例方法很少,其中一个很有用的就是count(也适用于列表),它可以统计某个值得出现频率:

In [34]: a = (1, 2, 2, 2, 3, 4, 2)

In [35]: a.count(2)
Out[35]: 4

2,列表

与元组相比列表格式,长度及内容均可以进行修改,可以用方括号定义,或者用list函数

#使用方括号定义列表
In [36]: a_list = [2, 3, 7, None]

In [37]: tup = ('foo', 'bar', 'baz')
#使用list函数把元组转化为列表
In [38]: b_list = list(tup)

In [39]: b_list
Out[39]: ['foo', 'bar', 'baz']
#列表中的元素可以直接进行修改
In [40]: b_list[1] = 'peekaboo'

In [41]: b_list
Out[41]: ['foo', 'peekaboo', 'baz']

list函数还可以用来实体化迭代器或生成器

In [42]: gen = range(10)

In [43]: gen
Out[43]: range(0, 10)

In [44]: list(gen)
Out[44]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2.2 列表添加和删除元素

可以使用append在末尾添加元素

In [45]: b_list.append('dwarf')

In [46]: b_list
Out[46]: ['foo', 'peekaboo', 'baz', 'dwarf']

insert可以在任意位置插入元素
insert函数有两个参数,第一个是要插入的位置,第二个是要插入的内容
在指定位置插入元素,指定位置原来的元素及之后的元素往后顺移
插入的序号必须在 0 和列表长度之间。

警告:与append相比,insert耗费的计算量大,因为对后续元素的引用必须在内部迁移,以便为新元素提供空间。如果要在序列的头部和尾部插入元素,你可能需要使用collections.deque,一个双尾部队列。

In [46]: b_list
Out[46]: ['foo', 'peekaboo', 'baz', 'dwarf']
#insert函数有两个参数,第一个是要插入的位置,第二个是要插入的内容
#在指定位置插入元素,指定位置原来的元素及之后的元素往后顺移
In [47]: b_list.insert(1, 'red')
In [48]: b_list
Out[48]: ['foo', 'red', 'peekaboo', 'baz', 'dwarf']

insert函数的逆运算函数是pop函数,它可以移除指定位置的元素,并返回此元素
pop函数只有一个参数就是要移除的参数的位置

In [48]: b_list
Out[48]: ['foo', 'red', 'peekaboo', 'baz', 'dwarf']

In [49]: b_list.pop(2)
Out[49]: 'peekaboo'

In [50]: b_list
Out[50]: ['foo', 'red', 'baz', 'dwarf']

可以使用remove函数,去除列表中某个值,remove函数会去除找到的第一个此值

In [51]: b_list.append('foo')

In [52]: b_list
Out[52]: ['foo', 'red', 'baz', 'dwarf', 'foo']

In [53]: b_list.remove('foo')

In [54]: b_list
Out[54]: ['red', 'baz', 'dwarf', 'foo']

用in可以判断列表是否包含某个值,用not in可以判断列表是否不包含某个值

In [55]: 'dwarf' in b_list
Out[55]: True

In [56]: 'dwarf' not in b_list
Out[56]: False


在列表中检查是否存在某个值远比字典和集合速度慢,因为 Python 是线性搜索列表中的值,但在字典和集合中,在同样的时间内还可以检查其它项(基于哈希表)。

2.3 串联和组合列表

与元组类似,可以用"+"把两个列表组合其他

In [57]: [4, None, 'foo'] + [7, 8, (2, 3)]
Out[57]: [4, None, 'foo', 7, 8, (2, 3)]

可以使用extend函数追加多个元素

In [58]: x = [4, None, 'foo']

In [59]: x.extend([7, 8, (2, 3)])

In [60]: x
Out[60]: [4, None, 'foo', 7, 8, (2, 3)]

通过加法将列表串联的计算量较大,因为要新建一个列表,并且要复制对象。用extend追加元素,尤其是到一个大列表中,更为可取。因此:

2.4 排序

可以使用sort函数对列表进行排序(sort函数是直接对原有列表进行排序,使用这个函数后原有列表将被改变,函数sorted()是产生一个排序列表的副本不改变原有的列表)

In [61]: a = [7, 2, 5, 1, 3]

In [62]: a.sort()

In [63]: a
Out[63]: [1, 2, 3, 5, 7]

sort函数有两个可选的参数
参与1:参数key是用来指定按照什么进行排序的,默认是——数字、字符串按照ASCII,中文按照unicode从小到大排序

In [64]: b = ['saw', 'small', 'He', 'foxes', 'six']

In [65]: b.sort(key=len)

In [66]: b
Out[66]: ['He', 'saw', 'six', 'small', 'foxes']

参数2:参数reverse是用来确定排序是降序还是升序的,默认是升序,当reverse = True时,为降序排序

In [64]: print(d_list) 
Out[66]: [1, 1, 2, 3, 5]
In [66]: d_list.sort(reverse = True)
In [66]: d_list
Out[66]: [5, 3, 2, 1, 1]
2.5 切片

切片可以截取列表的一部分,切片的基本形式是在方括号中使用start:stop:

In [73]: seq = [7, 2, 3, 7, 5, 6, 0, 1]

In [74]: seq[1:5]
Out[74]: [2, 3, 7, 5]

切片也可以进行赋值

In [75]: seq[3:4] = [6, 3]

In [76]: seq
Out[76]: [7, 2, 3, 6, 3, 5, 6, 0, 1]

切片的起始元素是包括的,不包含结束元素。因此,结果中包含的元素个数是stop - start。
start或stop都可以被省略,省略之后,分别默认序列的开头和结尾:

In [77]: seq[:5]
Out[77]: [7, 2, 3, 6, 3]

In [78]: seq[3:]
Out[78]: [6, 3, 5, 6, 0, 1]

切片也可以使用负数,负数表明从后向前切片:

In [79]: seq[-4:]
Out[79]: [5, 6, 0, 1]
In [80]: seq[-6:-2]
Out[80]: [6, 3, 5, 6]

两个冒号之后可以间隔取数,例如seq[::2]就是从头到尾进行切片且间隔一个进行取数

#注意seq[::-1]可以倒序进行切片,且只能从头到尾倒序切片,不能切一部分再倒序(这种返回的结果为空)
In [79]: seq,seq[1:5],seq[1:5:2],seq[::-1]
Out[80]: ([1, 3, 2, 4, 5, 6, 7], [3, 2, 4, 5], [3, 4], [7, 6, 5, 4, 2, 3, 1])

2.6 序列函数

enumerate函数
enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等
enumerate英文含义为列举,枚举

In [79]: for index,text in enumerate(x):
In [79]:     print('index',index),print('text',text)
Out[80]: 
text s
index 1
text t
index 2
text r
index 3
text i
index 4
text n
index 5
text g

sorted函数
sorted函数可以从任意序列中返回一个排列好的列表

In [87]: sorted([7, 1, 2, 6, 0, 3, 2])
Out[87]: [0, 1, 2, 2, 3, 6, 7]

In [88]: sorted('horse race')
Out[88]: [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']


sorted函数有两个可选参数,和sort函数是一样的,分别是key参数及reverse参数。

**zip函数**
zip函数,可以将多个列表,元组或其他序列,组成一个元组列表

```python
In [89]: seq1 = ['foo', 'bar', 'baz']

In [90]: seq2 = ['one', 'two', 'three']

In [91]: zipped = zip(seq1, seq2)
#zip函数返回的结果需要用list函数列表化
In [92]: list(zipped)
Out[92]: [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]

zip函数可以组合多个任意长度的序列,返回列表的长度取决于最短的序列

In [93]: seq3 = [False, True]

In [94]: list(zip(seq1, seq2, seq3))
Out[94]: [('foo', 'one', False), ('bar', 'two', True)]

zip函数,可以把多个序列组合在一起形成一个元素为元组的列表,也可以使用zip函数把一个元素为元组的列表拆成多个元组

In [96]: pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
   ....:             ('Schilling', 'Curt')]

In [97]: first_names, last_names = zip(*pitchers)

In [98]: first_names
Out[98]: ('Nolan', 'Roger', 'Schilling')

In [99]: last_names
Out[99]: ('Ryan', 'Clemens', 'Curt')

reversed函数
reversed可以从后向前迭代一个序列:

In [100]: list(reversed(range(10)))
Out[100]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

3,字典

字典可能是 Python 最为重要的数据结构。它更为常见的名字是哈希映射或关联数组。它是键值对的大小可变集合,键和值都是 Python 对象。创建字典的方法之一是使用尖括号,用冒号分隔键和值:
键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。

In [101]: empty_dict = {}

In [102]: d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}

In [103]: d1
Out[103]: {'a': 'some value', 'b': [1, 2, 3, 4]}

字典可以像列表一样,访问,插入或设定字典的元素

In [104]: d1[7] = 'an integer'

In [105]: d1
Out[105]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}

In [106]: d1['b']
Out[106]: [1, 2, 3, 4]

可以像检查列表或元组那样,检查字典是否包含某个(注意这里说的是键不是元素)

In [107]: 'b' in d1
Out[107]: True

可以使用del关键字,或者pop方法删除字典中的某个值(返回值的同时删除键)

In [108]: d1[5] = 'some value'

In [109]: d1
Out[109]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 5: 'some value'}

In [110]: d1['dummy'] = 'another value'

In [111]: d1
Out[111]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 5: 'some value',
 'dummy': 'another value'}

In [112]: del d1[5]

In [113]: d1
Out[113]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 'dummy': 'another value'}

In [114]: ret = d1.pop('dummy')

In [115]: ret
Out[115]: 'another value'

In [116]: d1
Out[116]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}

删除与清除字典
能删单一的元素也能清空字典,清空只需一项操作。

显示删除一个字典用del命令,如下实例

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
 
del tinydict['Name']  # 删除键是'Name'的条目
tinydict.clear()      # 清空字典所有条目
del tinydict          # 删除字典
 
print "tinydict['Age']: ", tinydict['Age'] 
print "tinydict['School']: ", tinydict['School']

keys 和values 是字典的键和值的迭代器的方法,虽然字段没有顺序,但是这两个方法可以用相同的顺序输出键和值:

#用keys方法,返回的是一个迭代器,需要用list函数转化为字典才能显示出结果
In [117]: list(d1.keys())
Out[117]: ['a', 'b', 7]

In [118]: list(d1.values())
Out[118]: ['some value', [1, 2, 3, 4], 'an integer']

用update方法可以融合另一个字典

#update方法是原地改变字典,因此任何传递给update的键的旧的值都会被舍弃。
In [119]: d1.update({'b' : 'foo', 'c' : 12})

In [120]: d1
Out[120]: {'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}

3.2 用序列创建字典

可以用for循环的方法,把两个序列合并为字典(一个序列为键,一个序列为值)

In [120]: 	l1 = list(range(5))
			l2 = list(reversed(range(5)))
			d2 = {}
			#使用zip函数把两个列表合并为一个元组
			for key,value in zip(l1,l2):
	    		d2[key] = value
			d2
Out[120]: {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}

因为字典本质上说2元元组的集合,因此2元元组可以直接转化为字典

In [121]: mapping = dict(zip(range(5), reversed(range(5))))

In [122]: mapping
Out[122]: {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}

3.3 字典常用函数

1 cmp(dict1, dict2)
比较两个字典元素。
2 len(dict)
计算字典元素个数,即键的总数。
3 str(dict)
输出字典可打印的字符串表示。
4 type(variable)
返回输入的变量类型,如果变量是字典就返回字典类型。

1 dict.clear()
删除字典内所有元素
2 dict.copy()
返回一个字典的浅复制
3 dict.fromkeys(seq[, val])
创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
4 dict.get(key, default=None)
返回指定键的值,如果值不在字典中返回default值
5 dict.has_key(key)
如果键在字典dict里返回true,否则返回false
6 dict.items()
以列表返回可遍历的(键, 值) 元组数组
7 dict.keys()
以列表返回一个字典所有的键
8 dict.setdefault(key, default=None)
和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9 dict.update(dict2)
把字典dict2的键/值对更新到dict里
10 dict.values()
以列表返回字典中的所有值
11 pop(key[,default])
删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
12 popitem()
返回并删除字典中的最后一对键和值。

4,集合

集合是无序的不可重复的元素的集合,你可以把它当做字典,但是只有键没有值。可以用两种方式创建集合:通过set函数或使用尖括号set语句:

In [133]: set([2, 2, 2, 1, 3, 3])
Out[133]: {1, 2, 3}

In [134]: {2, 2, 2, 1, 3, 3}
Out[134]: {1, 2, 3}

集合支持合并、交集、差分和对称差等数学集合运算。考虑两个示例集合:

In [135]: a = {1, 2, 3, 4, 5}

In [136]: b = {3, 4, 5, 6, 7, 8}

合并是取两个集合中不重复的元素。可以用union方法,或者|运算符:

In [137]: a.union(b)
Out[137]: {1, 2, 3, 4, 5, 6, 7, 8}

In [138]: a | b
Out[138]: {1, 2, 3, 4, 5, 6, 7, 8}

交集的元素包含在两个集合中。可以用intersection或&运算符:

In [139]: a.intersection(b)
Out[139]: {3, 4, 5}

In [140]: a & b
Out[140]: {3, 4, 5}

常见的集合方法
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值