1元组,列表,字符串的共同特点
都可以通过索引获取每一个元素
第一个元素的索引值都是0
都可以通过的切片的方法获得一个范围内的元素集合
有很多共同的运算符
因此,列表,元组和字符串,都称为系列
2加好乘号
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> (1, 2, 3) + (4, 5, 6)
(1, 2, 3, 4, 5, 6)
>>> "123" + "456"
'123456'
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> (1, 2, 3) * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> "123" * 3
'123123123'
3关于可变和不可变
可变系列
>>> s = [1, 2, 3]
>>> id(s)
2285532322944
>>> s *= 2
>>> s
[1, 2, 3, 1, 2, 3]
>>> id(s)
2285532322944
不可变序列
>>> t = (1, 2, 3)
>>> id(t)
2285532205952
>>> t *= 2
>>> t
(1, 2, 3, 1, 2, 3)
>>> id(t)
2285532393920
4是和不是
是(is)和不是(is not)被称之为同一性运算符,用于检测两个对象之间的 id 值是否相等:
>>> x = "FishC"
>>> y = "FishC"
>>> x is y
True
>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> x is not y
True
5包含和不包含
in 运算符是用于判断某个元素是否包含在序列中的,而 not in 则恰恰相反:
>>> "Fish" in "FishC"
True
>>> "鱼" in "鱼C"
True
>>> "C" not in "FishC"
False
6del语句
del 语句用于删除一个或多个指定的对象:
>>> x = "FishC"
>>> y = [1, 2, 3]
>>> del x, y
>>> x
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
x
NameError: name 'x' is not defined
>>> y
Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
y
NameError: name 'y' is not defined
7list(),tuple()和str()
list()、tuple() 和 str() 这三个 BIF 函数主要是实现列表、元组和字符串的转换。
8min()和max()
min()和max()这两个函数的功能是:对比传入的参数,并返回最小值和最大值
min(iterable, *[, key, default])
min(arg1, arg2, *args[, key])
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
这第一种传入的是一个可迭代对象
>>> s = [1, 1, 2, 3, 5]
>>> min(s)
1
>>> t = "FishC"
>>> max(t)
's'
这第二种传入多个参数,它们会自动找出其中的最小值和最大值:
>>> min(1, 2, 3, 0, 6)
0
>>> max(1, 2, 3, 0, 6)
6
9len()和sum()
len() 函数我们前面用过好多次了,基本用法不必啰嗦,大家都懂~不过它有个最大的可承受范围,可能有些同学还不知道,比如说这样
>>> len(range(2 ** 100))
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
len(range(2 ** 100))
OverflowError: Python int too large to convert to C ssize_t
这个错误是由于 len() 函数的参数太大导致的,我们知道 Python 为了执行的效率,它内部几乎都是用效率更高的 C 语言来实现的。
而这个 len() 函数为了让 Python 自带的数据结构可以走后门,它会直接读取 C 语言结构体里面对象的长度。
所以,如果检测的对象超过某个数值,就会出错。
通常对于 32 位平台来说,这个最大的数值是 2**31 - 1;而对于 64 位平台来说,这个最大的数值是 2**63 - 1。
sum()函数用于计算迭代对象中各项的和:
>>> s = [1, 0, 0, 8, 6]
>>> sum(s)
15
它有一个 start 参数,用于指定求和计算的起始数值,比如这里我们设置为从 100 开始加起:
>>> sum(s, start=100)
115
10sorted()和reversed()
sorted()函数将重新排序iterable参数中的元素,并将结果返回一个新的liebiap:
>>> s = [1, 2, 3, 0, 6]
>>> sorted(s)
[0, 1, 2, 3, 6]
sorted() 函数也支持 key 和 reverse 两个参数,用法跟列表的 sort() 方法一致:
>>> sorted(s, reverse=True)
[6, 3, 2, 1, 0]
>>> s.sort(reverse=True)
>>> s
[6, 3, 2, 1, 0]
>>> t = ["FishC", "Apple", "Book", "Banana", "Pen"]
>>> sorted(t)
['Apple', 'Banana', 'Book', 'FishC', 'Pen']
>>> sorted(t, key=len)
['Pen', 'Book', 'FishC', 'Apple', 'Banana']
sorted(t, key=len) 这个,因为这个 key 参数,指定的是一个干预排序算法的函数。
比如这里我们指定为 len() 函数,那么 Python 在排序的过程中,就会先将列表中的每一个元素调用一次 len() 函数,然后比较的是 len() 返回的结果。
所以,sorted(t, key=len) 比较的就是每个元素的长度。
reverse()函数将返回参数的迭代器
>>> s = [1, 2, 5, 8, 0]
>>> reversed(s)
<list_reverseiterator object at 0x0000022926732AC0>
大家看,它不是直接返回所见即所得的结果,它返回的一串奇奇怪怪的英文……
刚刚我们说过,它返回的结果是一个迭代器,并且我们可以把它当可迭代对象处理。
既然如此,我们就可以使用 list() 函数将其转换为列表:
>>> list(reversed(s))
[0, 8, 5, 2, 1]
reversed() 函数也同样支持任何形式的可迭代对象:
>>> list(reversed("FishC"))
['C', 'h', 's', 'i', 'F']
>>> list(reversed((1, 2, 5, 9, 3)))
[3, 9, 5, 2, 1]
>>> list(reversed(range(0, 10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
11all()和any()
all()函数是可判断迭代对象中是否所有元素都为真
any()函数是可判断迭代对象中是否存在元素为真
>>> x = [1, 1, 0]
>>> y = [1, 1, 9]
>>> all(x)
False
>>> all(y)
Ture
>>> any(x)
True
>>> any(y)
True
12enumerate
enumerate()函数用于返回一个枚举对象,它的功能就是将可迭代对象中的每个元素及从 0 开始的序号共同构成一个二元组的列表:
>>> seasons = ["Spring", "Summer", "Fall", "Winter"]
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
它有一个 start 参数,可以自定义序号开始的值:
>>> for i, j in enumerate(seasons, start=10):
... print(i, "->", j)
...
10 -> Spring
11 -> Summer
12 -> Fall
13 -> Winter
13zip()
做法是将作为参数传入的每个可迭代对象的每个元素依次组合成元组,即第 i 个元组包含来自每个参数的第 i 个元素。
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> z = [7, 8, 9]
>>> zipped = zip(x, y, z)
>>> list(zipped)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
这里有一点需要大家注意的,就是如果传入的可迭代对象长度不一致,那么将会以最短的那个为准:
>>> z = "FishC"
>>> zipped = zip(x, y, z)
>>> list(zipped)
[(1, 4, 'F'), (2, 5, 'i'), (3, 6, 's')]
当我们不关心较长的可迭代对象多出的数据时,使用 zip() 函数无疑是最佳的选择,因为它自动裁掉多余的部分。
但是,如果那些值对于我们来说是有意义的,我们可以使用 itertools 模块的 zip_longest() 函数来代替:
>>> import itertools
>>> zipped = itertools.zip_longest(x, y, z)
>>> list(zipped)
[(1, 4, 'F'), (2, 5, 'i'), (3, 6, 's'), (None, None, 'h'), (None, None, 'C')]
14map()
map()函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器:
>>> mapped = map(ord, "FishC")
>>> list(mapped)
[70, 105, 115, 104, 67]
如果指定的函数需要两个参数,后面跟着的可迭代对象的数量也应该是两个:
>>> mapped = map(pow, [2, 3, 10], [5, 2, 3]))
>>> list(mapped)
[32, 9, 1000]
上面代码其实就相当于是:
>>> [pow(2, 5), pow(3, 2), pow(10, 3)]
[32, 9, 1000]
可以看出,如果数量一多,使用 map() 函数要方便许多。
如果可迭代对象的长度不一致,那么 Python 采取的做法跟 zip() 函数一样,都是在最短的可迭代对象终止时结束:
>>> list(map(max, [1, 3, 5], [2, 2, 2], [0, 3, 9, 8]))
[2, 3, 9]
15filter()
与 map() 函数类似,filter() 函数也是需要传入一个函数作为参数,不过 filter() 函数是根据提供的函数,对指定的可迭代对象的每个元素进行运算,并将运算结果为真的元素,以迭代器的形式返回:
>>> filter(str.islower, "FishC")
<filter object at 0x000001B5170FEFA0>
上面代码我们传入的是字符串的 islower() 方法,作用就是判断传入的参数是否为小写字母,结合到 filter() 函数中使用,就是剔除大写字母,保留小写字母的作用。
如果提供的函数是 None,则会假设它是一个 “鉴真” 函数,即可迭代对象中所有值为假的元素会被移除:
>>> list(filter(None, [True, False, 1, 0]))
[True, 1]
16迭代器和可迭代对象
最大的区别是:可迭代对象咱们可以对其进行重复的操作,而迭代器则是一次性的!
将可迭代对象转换为迭代器:iter() 函数。
>>> x = [1, 2, 3, 4, 5]
>>> y = iter(x)
通过 type() 函数,我们可以观察到这个区别:
>>> type(x)
<class 'list'>
>>> type(y)
<class 'list_iterator'>
最后,BIF 里面有一个 next() 函数,它是专门针对迭代器的。
它的作用就是逐个将迭代器中的元素提取出来:
>>> next(y)
1
>>> next(y)
2
>>> next(y)
3
>>> next(y)
4
>>> next(y)
5
>>> next(y)
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
next(y)
StopIteration
现在如果不想它抛出异常,那么可以给它传入第二个参数:
>>> z = iter(x)
>>> next(z, "没啦,被你掏空啦~")
1
>>> next(z, "没啦,被你掏空啦~")
2
>>> next(z, "没啦,被你掏空啦~")
3
>>> next(z, "没啦,被你掏空啦~")
4
>>> next(z, "没啦,被你掏空啦~")
5
>>> next(z, "没啦,被你掏空啦~")
'没啦,被你掏空啦~'