摘要:# 创建元组的最简单⽅式,是⽤逗号分隔⼀列值a = 1,2,3a(1, 2, 3)type(a)tuple# 当⽤复杂的表达式定义元组,最好将值放到圆括号内a = ((1,2,3),(4,5,6),(7,8))
元组是⼀个固定⻓度,不可改变的Python序列对象。
# 创建元组的最简单⽅式,是⽤逗号分隔⼀列值a = 1,2,3a(1, 2, 3)type(a)tuple# 当⽤复杂的表达式定义元组,最好将值放到圆括号内a = ((1,2,3),(4,5,6),(7,8))a((1, 2, 3), (4, 5, 6), (7, 8))# ⽤tuple可以将任意序列或迭代器转换成元组a = tuple([1,2,3,4,5])a(1, 2, 3, 4, 5)s = tuple('hello')s('h', 'e', 'l', 'l', 'o')可以⽤⽅括号访问元组中的元素,索引从0开始。
s[1]'e'元组中存储的对象可能是可变对象。⼀旦创建了元组,元组中的对象就不能修改了。
s[0] = '1'TypeError Traceback (most recent call last)Cell In[19], line 1----> 1 s[0] = '1'TypeError: 'tuple' object does not support item assignment如果元组中的某个对象是可变的,⽐如列表,可以在原位进⾏修改。
a = ([1,2,3], 'hello', 'world', 4, 5, 6)a[0].append(4)a([1, 2, 3, 4], 'hello', 'world', 4, 5, 6)#可以⽤加号运算符将元组串联起来(1,2) + (3,4,5) + ('hello',)(1, 2, 3, 4, 5, 'hello')# 元组乘以⼀个整数,像列表⼀样,会将⼏个元组的复制串联起来(1,2)*5(1, 2, 1, 2, 1, 2, 1, 2, 1, 2)# 将元组赋值给类似元组的变量,Python会试图拆分等号右边的值x = (8,9,10)a,b,c = xa8b9c10# 含有元组的元组也会被拆分x = (7,8,(9,10))a,b,(c,d) = xa7b8c9d10# 变量替换a,b = 1,2a1b2a,b = b,aa2b1# 变量拆分常⽤来迭代元组或列表序列x = ((1,2,3),(4,5,6),(7,8,9))a,b,c = xa(1, 2, 3)b(4, 5, 6)c(7, 8, 9)特殊语法:*变量名 以抓取任意⻓度列表的位置参数,多数情况下,是表示想要舍弃的部分,作为惯⽤写法,许多Python程序员会将不需要的变量使⽤下划线。
a,*_ = xa(1, 2, 3)_因为元组的⼤⼩和内容不能修改,它的实例⽅法都很轻量。其中⼀个很有⽤的就是count(也适⽤于列表),它可以统计某个值得出现频率。
a = (1,2,2,1,3,2,1,5,1,2,3,3,2,1,6,5)a.count(3)3与元组对⽐,列表的⻓度可变、内容可以被修改。
# 用方括号定义x = [1,2,3,4,5]x[1, 2, 3, 4, 5]# 用list函数定义t = ('hello', ' ', 'world', '!')y = list(t)y['hello', ' ', 'world', '!']y[3] = '.'y['hello', ' ', 'world', '.']列表和元组的语义接近,在许多函数中可以交叉使⽤。
list函数也可以用来在数据处理中实体化迭代器或⽣成器:
g = range(0,10)grange(0, 10)list(g)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]append - 在列表末尾添加元素。y.append('China')y['hello', ' ', 'world', '.', 'China']insert 在特定的位置插⼊元素。#插⼊的序号必须在0和列表⻓度之间。y.insert(3, '!')y['hello', ' ', 'world', '!', '.', 'China']pop - 移除并返回指定位置的元素y.pop(4)'.'y['hello', ' ', 'world', '!', 'China']remove - 移除某个值,先寻找第⼀个值并除去
y.append('!')y.remove('!')y['hello', ' ', 'world', 'China', '!']in - 检查列表是否包含某个值# 与元组类似,可以用加号号将两个列表串联起来[1,2,3] + ['one','two','three'][1, 2, 3, 'one', 'two', 'three']# 列表的extend⽅法可以追加多个元素x = [1,2,3]x[1, 2, 3]x.extend([4,5,6])x[1, 2, 3, 4, 5, 6]通过加法将列表串联的计算量较⼤,因为要新建⼀个列表,并且要复制对象。而用extend追加元素,尤其是到⼀个⼤列表中,更为可取。
sort - 该函数在不创建新的对象的情况下将⼀个列表原地排序。a = [9,7,5,2,1,3,6,2,5,8,10]a.sorta[1, 2, 2, 3, 5, 5, 6, 7, 8, 9, 10]sort 函数的选型 key
b = ['saw', 'small', 'He', 'foxes', 'six']# 按字符串⻓度对字符串进⾏排序b.sort(key=len)b['He', 'saw', 'six', 'small', 'foxes']bisect模块⽀持⼆分查找和向已排序的列表插⼊值。
bisect.bisect可以找到插⼊值后仍保证排序的位置。bisect.insort是向这个位置插⼊值。a[1, 2, 2, 3, 5, 5, 6, 7, 8, 9, 10]import bisectbisect.bisect(a, 2)3a[1, 2, 2, 3, 5, 5, 6, 7, 8, 9, 10]bisect.insort(a, 2)a[1, 2, 2, 2, 3, 5, 5, 6, 7, 8, 9, 10]bisect模块不会检查列表是否已排好序,进⾏检查的话会耗费⼤量计算。因此,对未排序的列表使⽤bisect不会产⽣错误,但结果不⼀定正确。
⽤切片可以选取⼤多数序列类型的⼀部分,切⽚的基本形式是在⽅括号中使⽤start:stop
a[2:5][2, 2, 3]# 切片赋值a[2:5] = [10,10,10,10]a[1, 2, 10, 10, 10, 10, 5, 5, 6, 7, 8, 9, 10]切⽚的起始元素是包括的,不包含结束元素。因此,结果中包含的元素个数是stop - start。start或stop都可以被省略,省略之后,分别默认序列的开头和结尾。[1, 2, 10, 10, 10]a[5:][10, 5, 5, 6, 7, 8, 9, 10]负数表明从后向前切⽚a[-5:-2][8, 9, 10]a[:-3][1, 2, 10, 10, 10, 10, 5, 5, 6, 7]在第⼆个冒号后⾯使⽤step# 隔⼀个取⼀个元素a[::2][1, 10, 10, 5, 6, 8, 10]# step使⽤-1,它可以将列表或元组颠倒过来a[::-1][10, 9, 8, 7, 6, 5, 5, 10, 10, 10, 10, 2, 1]enumeratePython内建的enumerate函数,可以返回(index, value)元组序列,其中index为当前项的序号,value为值。
x = list(range(10))for index, value in enumerate(x):print('{0}:{1}'.format(index, value))0:01:12:23:34:45:56:67:78:89:9# 计算序列(唯⼀的)dict 映射到位置的值y = ['abc', 'def', 'xyz', 'mnl', 'ijk']d = {}for index, value in enumerate(y):d[value] = indexd{'abc': 0, 'def': 1, 'xyz': 2, 'mnl': 3, 'ijk': 4}sorted可以从任意序列的元素返回⼀个新的排好序的列表。
k = [9,0,1,7,2,3,8,6,5,8]sorted(k)[0, 1, 2, 3, 5, 6, 7, 8, 8, 9]sorted('hello world')[' ', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']# sorted函数可以接受和sort相同的参数k = ['1','123456','555','9080']sorted(k, key=len)['1', '555', '9080', '123456']zipzip可以将多个列表、元组或其它序列成对组合成⼀个元组列表。 zip可以处理任意多的序列,元素的个数取决于最短的序列。
a = list(range(5))a[0, 1, 2, 3, 4]b = ['a', 'b', 'c']b['a', 'b', 'c']c = ['x', 'y', 'z']c['x', 'y', 'z']list(zip(a,b))[(0, 'a'), (1, 'b'), (2, 'c')]list(zip(a,c))[(0, 'x'), (1, 'y'), (2, 'z')]list(zip(a,b,c))[(0, 'a', 'x'), (1, 'b', 'y'), (2, 'c', 'z')]zip的常⻅⽤法之⼀是同时迭代多个序列,可能结合enumerate使⽤。
for index, value in enumerate(zip(a,b,c)):print('{0} : {1}'.format(index, value))0 : (0, 'a', 'x')1 : (1, 'b', 'y')2 : (2, 'c', 'z')给出⼀个“被压缩的”序列,zip可以被⽤来解压序列。也可以当作把⾏的列表转换为列的列表。
z = zip(a,b)(m,n)=zip(*z)m(0, 1, 2)n('a', 'b', 'c')reversedreversed可以从后向前迭代⼀个序列。reversed是⼀个⽣成器,只有实体化(即列表或for循环)之后才能创建翻转的序列。
list(reversed(range(10)))[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]字典是Python最为重要的数据结构。更为常⻅的名字是哈希映射或关联数组。它是键值对的⼤⼩可变集合,键和值都是Python对象。 创建字典的⽅法之⼀是使⽤花括号,⽤冒号分隔键和值。
e = {} # 空字典e{}d1 = {'one': 10, 'two': 5, 'three': 9}d1{'one': 10, 'two': 5, 'three': 9}访问、插⼊或设定字典中的元素与访问列表或元组中的元素⼀样。
d1['one']10d1['four'] = 8d1{'one': 10, 'two': 5, 'three': 9, 'four': 8}可以⽤检查列表和元组是否包含某个值得⽅法,检查字典中是否包含某个键。
'five' in d1False'two' in d1True可以⽤del关键字或pop⽅法(返回值得同时删除键)删除值。
del d1['four']d1{'one': 10, 'two': 5, 'three': 9}d1.pop('two')5d1{'one': 10, 'three': 9}keys和values是字典的键和值的迭代器⽅法。虽然键值对没有顺序,这两个⽅法可以⽤相同的顺序输出键和值。
list(d1.keys)['one', 'three']list(d1.values)[10, 9]⽤update⽅法可以将⼀个字典与另⼀个融合。update⽅法是原地改变字典,因此任何传递给update的键的旧的值都会被舍弃。
d1.update({'two': 8, 'four': 9, 'five': 7})d1{'one': 10, 'three': 9, 'two': 8, 'four': 9, 'five': 7}# 想将两个序列配对组合成字典k = ['王波', '赵雷', '刘静宇']v = [90,92,98]d = {}for key, value in zip(k, v):d[key] = valued{'王波': 90, '赵雷': 92, '刘静宇': 98}#因为字典本质上是二元元组的集合,dict可以接受二元元组的列表m = dict(zip(k,v))m字典中与默认值相关的方法:get、pop、setdefault
字典的get方法,可以使用默认值返回。如果不指定默认值,get 会返回None。
m.get('赵波') is NoneTruem.get('赵波', 100)100而字典的pop方法,在没有指定默认值的情况下,如果不存在键,pop会抛出⼀个例外
m.pop('赵波')KeyError Traceback (most recent call last)Cell In[136], line 1----> 1 m.pop('赵波')KeyError: '赵波'm.pop('赵波', 100)100接下来,先看一个示例:将一个单词列表按首字母形成字典。
words = ['apple','better','an','cancel','can','ask','cache','bed','cell','back']firstLetter = {}for word in words:letter = word[0]if letter in firstLetter.keys:firstLetter[letter].append(word)else:firstLetter[letter] = [word]firstLetter{'a': ['apple', 'an', 'ask'],'b': ['better', 'bed', 'back'],'c': ['cancel', 'can', 'cache', 'cell']}上面的代码中,如果使用setdefault⽅法,则代码会简化:
firstLetter = {}for word in words:letter = word[0]firstLetter.setdefault(letter, ).append(word)firstLetter{'a': ['apple', 'an', 'ask'],'b': ['better', 'bed', 'back'],'c': ['cancel', 'can', 'cache', 'cell']}collections模块有⼀个很有⽤的类 defaultdict,它可以进⼀步简化上⾯的代码,传递类型或函数以⽣成每个位置的默认值:
from collections import defaultdictfirstLetter = defaultdict(list)for word in words:letter = word[0]firstLetter[letter].append(word)firstLetterdefaultdict(list,{'a': ['apple', 'an', 'ask'],'b': ['better', 'bed', 'back'],'c': ['cancel', 'can', 'cache', 'cell']})字典的值可以是任意Python对象,⽽键通常是不可变的标量类型(整数、浮点型、字符串)或元组(元组中的对象必须是不可变的)。这被称为“可哈希性”。可以⽤hash函数检测⼀个对象是否是可哈希的(可被⽤作字典的键)。
hash(1)1hash(3.14)322818021289917443hash('hello')-7107229069575945720hash((1,2,3))529344067295497451hash([1,2,3])TypeError Traceback (most recent call last)Cell In[162], line 1----> 1 hash([1,2,3])TypeError: unhashable type: 'list'要⽤列表当做键,⼀种⽅法是将列表转化为元组,只要内部元素可以被哈希,它也就可以被哈希。
d = {}d[tuple([1,2,3])] = 6d{(1, 2, 3): 6}集合是⽆序的不可重复的元素的集合。可以⽤两种⽅式创建集合:通过set函数或使⽤花括号set语句。
a = set(range(10))a{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}b = {1,2,2,2,3,3,3,3,4,4,5,5,6}b{1, 2, 3, 4, 5, 6}a.add(x) - 将元素 x 添加到集合 a 中a.clear - 将集合清空a.remove(x) - 将元素 x 从集合 a 除去a.pop - 从集合 a 去除任意元素,如果集合为空,则抛出 KeyError 错误a.union(b) - 表达式 a | b,集合 a 和 b 中所有不重复元素合并(并集)a.update(b) - 表达式 a |= b,设定集合 a 中的元素为 a 与 b 的合并a.intersection(b) - 表达式 a & b,a 和 b 中交叉的元素(交集)a.intersection_update(b) - 表达式a &= b,设定集合 a 中的元素为 a 与 b 的交叉a.difference(b) - 表达式 a - b,存在于 a 但不存在于 b 的元素(差集)a.difference_update(b) - 表达式 a -= b,设定集合 a 中的元素为 a 与 b 的差a.symmetric_difference(b) - 表达式 a ^ b,只在 a 或只在 b 的元素a = {1,2,3,4,5,6}b = {3,5,6,7,8,9}# 合并a | b{1, 2, 3, 4, 5, 6, 7, 8, 9}a & b{3, 5, 6}a - b{1, 2, 4}a ^ b{1, 2, 4, 7, 8, 9}所有逻辑集合操作都有另外原地实现⽅法,它可以直接⽤结果替代集合的内容。对于⼤的集合,这么做效率更⾼。
c = a.copyc |= bc{1, 2, 3, 4, 5, 6, 7, 8, 9}c = a.copyc &= bc{3, 5, 6}issubset - 检测⼀个集合是否是另⼀个集合的⼦集issuperset - 检测⼀个集合是否是另⼀个集合的⽗集aset = {1,2,3,4,5}{1,2,3}.issubset(aset)Trueaset.issuperset({1,2,3})True允许⽤户⽅便的从⼀个集合过滤元素,形成列表,在传递参数的过程中还可以修改元素。 格式:[expr for val in collection if condition]
# 给定⼀个字符串列表,过滤出⻓度在3及以下的字符串,并将其转换成⼤写ss = ['a','aa','aaaaa','bb','bbb','bbbbbb','ccc','ccccc','ddd','ddddd'][x.upper for x in ss if len(x) ['A', 'AA', 'BB', 'BBB', 'CCC', 'DDD']集合的推导式与列表很像,只不过⽤的是花括号。
cc = {'a','aa','aaaaa','bb','bbb','bbbbbb','ccc','ccccc','ddd','ddddd'}{x.upper for x in ss if len(x) {'A', 'AA', 'BB', 'BBB', 'CCC', 'DDD'}在Python中,字典推导式(Dictionary Comprehension)是一种创建字典的简洁方法,类似于列表推导式(List Comprehension),用于创建字典。它允许你通过一个表达式来生成字典的键值对。 格式:{key_expression: value_expression for variable in iterable}
# 从列表创建字典a = [1,2,3,4,5]{x : x*x for x in a if x%2!=0}{1: 1, 3: 9, 5: 25}# 从另一个字典创建字典d = {'王波': 90, '赵雷': 92, '刘静宇': 58}{key: '及格' if value >= 60 else '不及格' for key, value in d.items}{'王波': '及格', '赵雷': '及格', '刘静宇': '不及格'}# 对二维数组进行扁平化a = [(1,2,3),(4,5,6),(7,8,9)][x for b in a for x in b][1, 2, 3, 4, 5, 6, 7, 8, 9]for表达式的顺序是与嵌套for循环的顺序⼀样(⽽不是列表推导式的顺序)。
来源:IT职业教育