Skip to content

Python中的数据结构-元组|序列|集合|字典

元组和序列

列表和字符串具有很多共同的属性,如索引和切片操作。它们是 序列 数据类型的两个例子。还有另一种标准序列数据类型:元组。

# 元组由逗号分割的若干值组成,例如:
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

一个特殊的情况是构造包含 0 个或 1 个元素的元组

# 为了实现这种情况,语法上有一些奇怪。空元组由一对空括号创建;只有一个元素的元组由值后面跟随一个逗号创建
>>> empty = ()
>>> singleton = 'hello',    # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)

语句t = 12345, 54321, ‘hello!’ 是一个元组封装的例子: 值12345, 54321 和 ‘hello!’ 被一起放入一个元组。

其逆操作是序列分拆:x, y, z = t 。序列分拆要求等号左侧的变量和序列中的元素的数目相同。注意多重赋值只是同时进行元组封装和序列分拆。

>>> t = 12345, 54321, 'hello!'
>>> t
(12345, 54321, 'hello!')
>>> x, y, z = t
>>> x
12345
>>> y
54321
>>> z
'hello!'
>>> 


集合:

集合中的元素不会重复且没有顺序。集合的基本用途包括成员测试和消除重复条目。集合对象还支持并集、 交集、 差和对称差等数学运算。

花大括号或 set() 函数可以用于创建集合。注意: 若要创建一个空集必须使用set(),而不能用 {};后者将创建一个空的字典。

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # letters in both a and b
{'a', 'c'}
>>> a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

和 列表解析 类似,Python 也支持集合解析

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}

字典:

与序列不同,序列由数字做索引,字典由 键 做索引,键可以是任意不可变类型;字符串和数字永远可以拿来做键。

如果元组只包含字符串、 数字或元组,它们可以用作键;如果元组直接或间接地包含任何可变对象,不能用作键。

不能用列表作为键,因为列表可以用索引、切片或者 append() 和extend() 方法修改。

理解字典的最佳方式是把它看做无序的 键:值  对集合,要求是键必须是唯一的(在同一个字典内)。一对大括号将创建一个空的字典: {}。

list(d.keys())返回字典中所有键组成的列表,列表的顺序是随机的(如果你想它是有序的,只需使用sorted(d.keys())代替)。要检查某个键是否在字典中,可以使用 in 关键字。

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

dict() 构造函数直接从键-值对序列创建字典:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}

字典解析可以用于从任意键和值表达式创建字典:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

如果键都是简单的字符串,有时通过关键字参数指定 键-值 对更为方便:

>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}


遍历的技巧:

字典遍历时,键和对应的值通过使用items()方法可以同时得到。

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

序列中遍历时,使用 enumerate() 函数可以同时得到索引和对应的值。

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe

同时遍历两个或更多的序列,使用 zip() 函数可以成对读取元素。

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

要反向遍历一个序列,首先正向生成这个序列,然后调用 reversed() 函数。

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

按排序顺序遍历一个序列,请使用sorted()函数,返回一个新的排序的列表,同时保留源不变。

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

若要在遍历内部修改正在迭代的序列(例如复制某些元素),建议您首先制作副本。在序列上循环不会隐式地创建副本。切片表示法使这尤其方便:

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

深入条件控制:

while 和 if 语句中使用的条件可以包含任意的操作,而不仅仅是比较。

比较运算符 in 和 not in 检查一个值是否在一个序列中出现(不出现)。

is 和 is not 比较两个对象是否为同一对象;这只和列表这样的可变对象有关。

所有比较运算符都具有相同的优先级,低于所有数值运算符。
可以级联比较。例如, a < b == c 测试 a 是否小于 b 并且 b 等于 c。
可将布尔运算符 and 和 or 用于比较,比较的结果(或任何其他的布尔表达式)可以用 not 取反。

这些操作符的优先级又低于比较操作符;它们之间,not 优先级最高,or 优先级最低,所以 A and not B or C 等效于 (A and (not B)) or C。

布尔运算符and 和 or 是所谓的 短路 运算符:依参数从左向右求值,结果一旦确定就停止。

例如,如果A 和 C 都为真,但B是假, A and B and C 将不计算表达式 C。

用作一个普通值而非逻辑值时,短路操作符的返回值通常是最后一个计算的。

#可以把比较或其它逻辑表达式的返回值赋给一个变量。例如
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'

Published inPython

2 Comments

  1. admin admin

    厉害了我的王

    • 33 同志,啥都看啊。 -。-

发表评论

电子邮件地址不会被公开。 必填项已用*标注