元组:轻量级列表
元组创建于元素访问
>>> x = (1, 2, 3)
>>> type(x)
<class 'tuple'>
>>> x[0]
1
>>> x[-1]
3
>>> x[1]
2
>>> x[1] = 4 # 元组是不可变的
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> x = (3)
>>> x
3
>>> x[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
>>> x = (3,) # 如果元组中只有一个元素,必须在后面多写个逗号
>>> x[0]
3
>>> x = ()
>>> x = tuple()
>>> tuple(range(5))
(0, 1, 2, 3, 4)
>>> list(enumerate(range(5)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
>>> list(zip(range(3),'abcdefg'))
[(0, 'a'), (1, 'b'), (2, 'c')]
元组于列表的异同点
-
相同点
列表和元组都属于有序序列,都支持使用双向索引访问其中的元素
-
不同的点
元组属于不可变序列,不可直接修改元组中的元素的值,也无法为元组增加和删除元素,从一定程度上讲,可以认为元组是轻量级列表,或者“常量列表”
>>> x = ([1,2],3)
>>> x[0][0] = 5 # 修改元组中列表元素
>>>
>>> x
([5, 2], 3)
>>> x[0].append(8) # 为元组中列表增加元素
>>> x
([5, 2, 8], 3)
>>> x[0] = x[0] + [10] # 试图修改元组的值,失败
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> x
([5, 2, 8], 3)
>>> x[0] += [10] # 抛出异常,但元组中的元素已被修改
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> x
([5, 2, 8, 10], 3)
>>> y = x[0]
>>> y
[5, 2, 8, 10]
>>> y += [11]
>>> y
[5, 2, 8, 10, 11]
>>> x
([5, 2, 8, 10, 11], 3)
>>> y = y + [12]
>>> y
[5, 2, 8, 10, 11, 12]
>>> x
([5, 2, 8, 10, 11], 3)
# x = x + [3] 和 x += [3]有本质区别
>>> x = [1,2]
>>> id(x)
2666094589960
>>> x += [3]>>> id(x)2666094589960>>> x[1, 2, 3]>>> x = x + [4]>>> x[1, 2, 3, 4]>>> id(x)2666094590600
-
作为不可变序列,与整数、字符串一样,元组可用字典的键,也可以作为集合的元素,内置函数hash()可以用来测试一个对象是否可哈希,如果对象不可哈希会抛出异常
>>> hash((1,)) # 元组、数字、字符串都是可哈希的
3430019387558
>>> hash(3)
3
>>> hash('hello world.')
-4516426368981041408
>>> hash([1,2]) # 列表不可哈希的
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
生成器推导式
-
生成器推导式也称为生成器表达式,在形式上生成器推导式使用圆括号作为定界符,生成器推导式的结果是一个生成器对象,可以将其转换为列表或者元组,也可以使用生成器对象的next()方法或者内置函数next()进行遍历,或者使用for循环来遍历其中的元素,只能从前往后正向访问其中的元素,没有任何方法可以再次访问已访问过的元素
>>> g = ((i+2)**2 for i in range(10)) # 创建生成器对象
>>> g
<generator object <genexpr> at 0x0000026CBF9E93B8>
>>> list(g) # 将生成器对象转换为列表
[4, 9, 16, 25, 36, 49, 64, 81, 100, 121]
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> g.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> g = ((i+2)**2 for i in range(10))
>>> g.__next__()
4
>>> g.__next__()
9
>>> next(g)
16
>>> next(g)
25
>>> g = ((i+2)**2 for i in range(10))
>>> tuple(g)
(4, 9, 16, 25, 36, 49, 64, 81, 100, 121)
>>> g = ((i+2)**2 for i in range(10))
>>> for item in g:
... print(item,end=' ')
...
4 9 16 25 36 49 64 81 100 121 >>>
>>> x = filter(None,range(10))>>> 1 in xTrue>>> 5 in xTrue>>> 2 in x # 不可再访问已经访问过的元素False>>> x = map(str,range(10))>>> '0' in xTrue>>> '0' in xFalse