python集合和列表、安从小到大的顺序组合成一个字典_第3章 Python容器:列表、元组、字典与集合...
3.1 列表和元组
除字符串外,Python 还有另外两种序列结构:元组和列表。它们都可以包含零个或多个元
素。与字符串不同的是,元组和列表并不要求所含元素的种类相同,每个元素都可以是任
何 Python 类型的对象。得益于此,你可以根据自己的需求和喜好创建具有任意深度及复杂
度的数据结构。
为什么 Python 需要同时设定列表和元组这两种序列呢?这是因为元组是不可变的,当你给
元组赋值时,这些值便被固定在了元组里,再也无法修改。然而,列表却是可变的,这意
味着可以随意地插入或删除其中的元素
3.2 列表
列表非常适合利用顺序和位置定位某一元素,尤其是当元素的顺序或内容经常发生改变
时。与字符串不同,列表是可变的。你可以直接对原始列表进行修改:添加新元素、删除
或覆盖已有元素。在列表中,具有相同值的元素允许出现多次。
如果你仅仅想要记录一些互不相同的值,而不在乎它们之间的顺序关系, 集
合 (set)会是一个更好的选择
3.2.1 使用 [] 或 list() 创建列表
列表可以由零个或多个元素组成,元素之间用逗号分开,整个列表被方括号所包裹
>>> empty =[]>>> weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']>>>empty
[]>>>weekdays
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
也可以使用 list() 函数来创建一个空列表:
>>> another_empty_list =list()>>>another_empty_list
[]
3.2.2 使用 list() 将其他数据类型转换成列表
Python 的 list() 函数可以将其他数据类型转换成列表类型。
Python 的 list() 函数可以将其他数据类型转换成列表类型
>>> list('cat')
['c', 'a', 't']
将一个元组(在列表之后介绍)转换成了列表>>> a_tuple = ('ready', 'fire', 'aim')>>>list(a_tuple)
['ready', 'fire', 'aim']
使用 split() 可以依据分隔符将字符串切割成由若干子串组成的列表>>> birthday = '1/6/1952'
>>> birthday.split('/')
['1', '6', '1952']
如果待分割的字符串中包含连续的分隔符,那么在返回的列表中会出现空串元素>>> splitme = 'a/b//c/d///e'
>>> splitme.split('/')
['a', 'b', '', 'c', 'd', '', '', 'e']
把上面例子中的分隔符改成 // 则会得到如下结果>>> splitme.split('//')
['a/b', 'c/d', '/e']
3.2.3 使用 [offset] 获取元素
和字符串一样,通过偏移量可以从列表中提取对应位置的元素:
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>>marxes[0]'Groucho'
>>> marxes[1]'Chico'
>>> marxes[2]'Harpo'
>>> marxes[-1]'Harpo'
>>> marxes[-2]'Chico'
>>> marxes[-3]'Groucho'当指定的偏移量小于起始位置或者大于末尾位置时,会产生异常>>> marxes[5]
Traceback (most recent call last):
File"", line 1, in marxes[5]
IndexError: list index out of range>>> marxes[-4]
Traceback (most recent call last):
File"", line 1, in marxes[-4]
IndexError: list index out of range
3.2.4 包含列表的列表
>>> small_birds = ['hummingbird', 'finch']>>> extinct_birds = ['dodo', 'passenger pigeon', 'Norwegian Blue']>>> carol_birds = [3, 'French hens', 2, 'turtledoves']>>> all_birds = [small_birds, extinct_birds, 'macaw', carol_birds]>>>all_birds
[['hummingbird', 'finch'], ['dodo', 'passenger pigeon', 'Norwegian Blue'], 'macaw', [3, 'French hens', 2, 'turtledoves']]>>>all_birds[0]
['hummingbird', 'finch']>>> all_birds[1][0]'dodo'
3.2.5 使用 [offset] 修改元素
就像可以通过偏移量访问某元素一样,你也可以通过赋值对它进行修改:
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> marxes[2]'Harpo'
>>> marxes[2] = 'Wanda'
>>>marxes
['Groucho', 'Chico', 'Wanda']
通过这种方式无法修改字符串中的指定字符,因为字符串是不可变的。列表是可变的,因
此你可以改变列表中的元素个数,以及元素的值
3.2.6 指定范围并使用切片提取元素
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> marxes[0:2]
['Groucho', 'Chico']>>> marxes[::2]
['Groucho', 'Harpo']>>> marxes[::-2]
['Harpo', 'Groucho']>>> marxes[::-1]
['Harpo', 'Chico', 'Groucho']
3.2.7 使用 append() 添加元素至尾部
传统的向列表中添加元素的方法是利用 append() 函数将元素一个个添加到尾部。假设前
面的例子中我们忘记了添加 Zeppo,没关系,由于列表是可变的,可以方便地把它添加到
尾部:
>>> marxes.append('Zeppo')>>>marxes
['Groucho', 'Chico', 'Harpo', 'Zeppo']
3.2.8 使用 extend() 或 += 合并列表
使用 extend() 可以将一个列表合并到另一个列表中。一个好心人又给了我们一份 Marx 兄
弟的名字列表 others ,我们希望能把它加到已有的 marxes 列表中:
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> others = ['Gummo', 'Karl']>>>marxes.extend(others)>>>marxes
也可以使用+=['Groucho', 'Chico', 'Harpo', 'Zeppo', 'Gummo', 'Karl']>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> others = ['Gummo', 'Karl']>>> marxes +=others>>>marxes
['Groucho', 'Chico', 'Harpo', 'Zeppo', 'Gummo', 'Karl']
如果错误地使用了 append() ,那么 others 会被当成一个单独的元素进行添加,而不是将其
中的内容进行合并:>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> others = ['Gummo', 'Karl']>>>marxes.append(others)>>>marxes
['Groucho', 'Chico', 'Harpo', 'Zeppo', ['Gummo', 'Karl']]
3.2.9 使用 insert() 在指定位置插入元素
append() 函数只能将新元素插入到列表尾部,而使用 insert() 可以将元素插入到列表的任
意位置。指定偏移量为 0 可以插入列表头部。如果指定的偏移量超过了尾部,则会插入到
列表最后,就如同 append() 一样,这一操作不会产生 Python 异常。
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> marxes.insert(3, 'Gummo')>>>marxes
['Groucho', 'Chico', 'Harpo', 'Gummo', 'Zeppo']>>> marxes.insert(10, 'Karl')>>>marxes
['Groucho', 'Chico', 'Harpo', 'Gummo', 'Zeppo', 'Karl']
3.2.10 使用 del 删除指定位置的元素
del 是 Python 语句 ,而不是列表方法——无法通过 marxes[-2].del() 进行调
用。 del 就像是赋值语句( = )的逆过程:它将一个 Python 对象与它的名字
分离。如果这个对象无其他名称引用,则其占用空间也被会清除。
Python 语句还有 if...else.. for while 等等
>>>marxes
['Groucho', 'Chico', 'Harpo', 'Gummo', 'Zeppo', 'Karl']>>> del(marxes[1])>>>marxes
['Groucho', 'Harpo', 'Gummo', 'Zeppo', 'Karl']
3.2.11 使用 remove() 删除具有指定值的元素
如果不确定或不关心元素在列表中的位置,可以使用 remove() 根据指定的值删除元素。
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> marxes.remove('Chico')>>>marxes
['Groucho', 'Harpo', 'Zeppo']
3.2.12 使用 pop() 获取并删除指定位置的元素
使用 pop() 同样可以获取列表中指定位置的元素,但在获取完成后,该元素会被自动删除。
如果你为 pop() 指定了偏移量,它会返回偏移量对应位置的元素;如果不指定,则默认使
用 -1 。因此, pop(0) 将返回列表的头元素,而 pop() 或 pop(-1) 则会返回列表的尾元素:
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>>marxes.pop()'Zeppo'
>>>marxes
['Groucho', 'Chico', 'Harpo']>>> marxes.pop(1)'Chico'
>>>marxes
['Groucho', 'Harpo']
3.2.13 使用 index() 查询具有特定值的元素位置
如果想知道等于某一个值的元素位于列表的什么位置,可以使用 index() 函数进行查询:
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> marxes.index('Chico')1
3.2.14 使用 in 判断值是否存在
判断一个值是否存在于给定的列表中有许多方式,其中最具有 Python 风格的是使用 in
>>> marxes = ['Groucho', 'Chico', 'Harpo', 'Zeppo']>>> 'Groucho' inmarxes
True>>> 'Bob' inmarxes
False
同一个值可能出现在列表的多个位置,但只要至少出现一次,in就会返回 True :>>> words = ['a', 'deer', 'a' 'female', 'deer']>>> 'deer' inword
False
3.2.15 使用 count() 记录特定值出现的次数
使用 count() 可以记录某一个特定值在列表中出现的次数:
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> marxes.count('Chico')1
>>> marxes.count('Bob')
0>>> snl_skit = ['cheeseburger', 'cheeseburger', 'cheeseburger']>>> snl_skit.count('cheeseburger')3
3.2.16 使用 join() 转换为字符串
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> ','.join(marxes)'Groucho,Chico,Harpo'
你可能会觉得 join() 的使用顺序看起来有点别扭。这是因为 join() 实际上是一个
字符串方法,而不是列表方法。不能通过 marxes.join(',') 进行调用,尽管这可能看起来
更直观。 join() 函数的参数是字符串或者其他可迭代的包含字符串的序列(例如上面例
子中的字符串列表),它的输出是一个字符串。
试着这样来记忆 join() 的调用顺序:
join() 是 split() 的逆过程
>>> friends = ['Harry', 'Hermione', 'Ron']>>> separator = '*'
>>> joined =separator.join(friends)>>>joined'Harry * Hermione * Ron'
>>> separated =joined.split(separator)>>>separated
['Harry', 'Hermione', 'Ron']>>> separated ==friends
True
3.2.17 使用 sort() 重新排列元素
在实际应用中,经常需要将列表中的元素按值排序,而不是按照偏移量排序。Python 为此
提供了两个函数:
• 列表方法 sort() 会对原列表进行排序,改变原列表内容;
• 通用函数 sorted() 则会返回排好序的列表副本,原列表内容不变。
如果列表中的元素都是数字,它们会默认地被排列成从小到大的升序。如果元素都是字符
串,则会按照字母表顺序排列:
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> sorted_marxes =sorted(marxes)>>>sorted_marxes
['Chico', 'Groucho', 'Harpo']
sorted_marxes 是一个副本,它的创建并不会改变原始列表的内容:>>>marxes
['Groucho', 'Chico', 'Harpo']
但对 marxes 列表调用列表函数 sort() 则会改变它的内容:>>>marxes.sort()>>>marxes
['Chico', 'Groucho', 'Harpo']
当列表中的所有元素都是同一种类型时(例如 marxes 中都是字符串), sort() 会正常工
作。有些时候甚至多种类型也可——例如整型和浮点型——只要它们之间能够自动地互相
转换:>>> numbers = [2, 1, 4.0, 3, 33]>>>numbers.sort()>>>numbers
[1, 2, 3, 4.0, 33]
默认的排序是升序的,通过添加参数 reverse=True 可以改变为降序排列>>> numbers.sort(reverse=True)>>>numbers
[33, 4.0, 3, 2, 1]
3.2.18 使用 len() 获取长度
len() 可以返回列表长度
>>> numbers = [2, 1, 4.0, 3, 33]>>>len(numbers)5
3.2.19 使用 = 赋值,使用 copy() 复制
如果将一个列表赋值给了多个变量,改变其中的任何一处会造成其他变量对应的值也被修
改,如下所示:
>>> a = [1, 2, 3]>>>a
[1, 2, 3]>>> b =a>>>b
[1, 2, 3]>>> a[0] = 'surprise'
>>>a
['surprise', 2, 3]>>>b
['surprise', 2, 3]
通过下面任意一种方法,都可以将一个列表的值复制到另一个新的列表中:
• 列表 copy() 函数
• list() 转换函数
• 列表分片 [:]
测试初始时我们的列表叫作 a ,然后利用 copy() 函数创建 b ,利用 list() 函数创建 c ,并
使用列表分片创建 d :
>>> a = [1, 2, 3]>>> b =a.copy()>>> c =list(a)>>> d =a[:]>>> a[0] = 'interger list are boring'
>>>a
['interger list are boring', 2, 3]>>>b
[1, 2, 3]>>>c
[1, 2, 3]>>>d
[1, 2, 3]
3.3 元组
与列表类似,元组也是由任意类型元素组成的序列。与列表不同的是,元组是不可变的,
这意味着一旦元组被定义,将无法再进行增加、删除或修改元素等操作。因此,元组就像
是一个常量列表。
3.3.1 使用 () 创建元组
下面的例子展示了创建元组的过程,它的语法与我们直观上预想的有一些差别。
可以用 () 创建一个空元组:
>>> empty_tuple =()>>>empty_tuple
()
创建包含一个或多个元素的元组时,每一个元素后面都需要跟着一个逗号,即使只包含一
个元素也不能省略>>> one_marx = 'Groucho',>>>one_marx
('Groucho',)
如果创建的元组所包含的元素数量超过1,最后一个元素后面的逗号可以省略:>>> marx_tuple = 'Groucho', 'Chico', 'Harpo'
>>>marx_tuple
('Groucho', 'Chico', 'Harpo')
Python 的交互式解释器输出元组时会自动添加一对圆括号。你并不需要这么做——定义元
组真正靠的是每个元素的后缀逗号——但如果你习惯添加一对括号也无可厚非。可以用括
号将所有元素包裹起来,这会使得程序更加清晰:>>> marx_tuple = ('Groucho', 'Chico', 'Harpo')>>>marx_tuple
('Groucho', 'Chico', 'Harpo')
可以一口气将元组赋值给多个变量:>>> a, b, c =marx_tuple>>>a'Groucho'
>>>b
有时这个过程被称为元组解包。
可以利用元组在一条语句中对多个变量的值进行交换,而不需要借助临时变量:>>> password = 'swordfish'
>>> icecream = 'tuttifrutti'
>>> password, icecream =icecream, password>>>password'tuttifrutti'
>>>icecream'swordfish'tuple() 函数可以用其他类型的数据来创建元组:>>> marx_list = ['Groucho', 'Chico', 'Harpo']>>>tuple(marx_list)
('Groucho', 'Chico', 'Harpo')'Chico'
>>>c'Harpo'
3.3.2 元组与列表
在许多地方都可以用元组代替列表,但元组的方法函数与列表相比要少一些——元组没有
append() 、 insert() ,等等——因为一旦创建元组便无法修改。既然列表更加灵活,那为
什么不在所有地方都使用列表呢?原因如下所示:
• 元组占用的空间较小
• 你不会意外修改元组的值
• 可以将元组用作字典的键
• 命名元组 可以作为对象的替代
• 函数的参数是以元组形式传递的
这一节不会再介绍更多关于元组的细节了。实际编程中,更多场合用到的是列表和字典,
而接下来要介绍的就是字典结构。
3.4 字典
字典(dictionary)与列表类似,但其中元素的顺序无关紧要,因为它们不是通过像 0 或 1
的偏移量访问的。取而代之,每个元素拥有与之对应的互不相同的键(key),需要通过键
来访问元素。键通常是字符串,但它还可以是 Python 中其他任意的不可变类型:布尔型、
整型、浮点型、元组、字符串,以及其他一些在后面的内容中会见到的类型。字典是可变
的,因此你可以增加、删除或修改其中的键值对。
如果使用过只支持数组或列表的语言,那么你很快就会爱上 Python 里的字典类型。
在其他语言中,字典可能会被称作 关系型数组 、 哈希表 或 哈希图 。在
Python 中,字典(dictionary)还经常会被简写成 dict。
3.4.1 使用 {} 创建字典
用大括号( {} )将一系列以逗号隔开的键值对( key:value )包裹起来即可进行字典的创
建。最简单的字典是空字典,它不包含任何键值对:
>>> empty_dict ={}>>>empty_dict
{}
>>> bierce ={"day": "A period of twenty-four hours, mostly misspent","positive": "Mistaken at the top of one's voice","misfortune": "The kind of fortune that never misses",
}>>>bierce
{'day': 'A period of twenty-four hours, mostly misspent', 'positive': "Mistaken at the top of one's voice", 'misfortune': 'The kind of fortune that never misses'}
Python 允许在列表、元组或字典的最后一个元素后面添加逗号,这不会产生
任何问题。此外,在括号之间输入键值对来创建字典时并不强制缩进,我这
么做只是为了增加代码的可读性。
3.4.2 使用 dict() 转换为字典
可以用 dict() 将包含双值子序列的序列转换成字典。(你可能会经常遇到这种子序列,例
如“Strontium,90,Carbon,14”或者“Vikings,20,Packers,7”,等等。)每个子序列
的第一个元素作为键,第二个元素作为值。
可以对任何包含双值子序列的序列使用 dict() ,下面是其他例子
>>> lol = [ ['a', 'b'], ['c', 'd'], ['e', 'f'] ]>>>dict(lol)
{'a': 'b', 'c': 'd', 'e': 'f'}
包含双值元组的列表:>>> lot = [ ('a', 'b'), ('c', 'd'), ('e', 'f') ]>>>dict(lot)
{'a': 'b', 'c': 'd', 'e': 'f'}
包含双值列表的元组:>>> tol = ( ['a', 'b'], ['c', 'd'], ['e', 'f'] )>>>dict(tol)
{'a': 'b', 'c': 'd', 'e': 'f'}
双字符的字符串组成的列表:>>> los = [ 'ab', 'cd', 'ef']>>>dict(los)
{'a': 'b', 'c': 'd', 'e': 'f'}
双字符的字符串组成的元组:>>> tos = ( 'ab', 'cd', 'ef')>>>dict(tos)
{'a': 'b', 'c': 'd', 'e': 'f'}
双字符的字符串组成的列表:>>> tos_list = ['ab', 'cd', 'ef']>>>dict(tos_list)
{'a': 'b', 'c': 'd', 'e': 'f'}
3.4.3 使用 [key] 添加或修改元素
向字典中添加元素非常简单,只需指定该元素的键并赋予相应的值即可。如果该元素的键
已经存在于字典中,那么该键对应的旧值会被新值取代。如果该元素的键并未在字典中出
现,则会被加入字典。与列表不同,你不需要担心赋值过程中 Python 会抛出越界异常。
>>> pythons ={'Chapman': 'Graham','Cleese': 'John','Idle': 'Eric','Jones': 'Terry','Palin': 'Michael',
}>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Idle': 'Eric', 'Jones': 'Terry', 'Palin': 'Michael'}>>> pythons['Gilliam'] = 'Gerry'
>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Idle': 'Eric', 'Jones': 'Terry', 'Palin': 'Michael', 'Gilliam': 'Gerry'}>>> pythons['Gilliam'] = 'Terry'
>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Idle': 'Eric', 'Jones': 'Terry', 'Palin': 'Michael', 'Gilliam': 'Terry'}
记住,字典的键必须保证互不相同。这就是为什么在这里使用姓作为键,而不是使用
名——Monty Python 的成员中有两个都叫 Terry !如果创建字典时同一个键出现了两次,
那么后面出现的值会取代之前的值:
3.4.4 使用 update() 合并字典
使用 update() 可以将一个字典的键值对复制到另一个字典中去。
>>> pythons ={'Chapman': 'Graham','Cleese': 'John','Idle': 'Eric','Jones': 'Terry','Palin': 'Michael',
}>>> others = { 'Marx': 'Groucho', 'Howard': 'Moe'}>>>pythons.update(others)>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Idle': 'Eric', 'Jones': 'Terry', 'Palin': 'Michael', 'Marx': 'Groucho', 'Howard': 'Moe'}
如果待添加的字典与待扩充的字典包含同样的键会怎样?是的,新归入字典的值会取代原
有的值:
>>> first = {'a': 1, 'b': 2}>>> second = {'b': 'platypus'}>>>first.update(second)>>>first
{'a': 1, 'b': 'platypus'}
3.4.5 使用 del 删除具有指定键的元素
>>> pythons ={'Chapman': 'Graham','Cleese': 'John','Idle': 'Eric','Jones': 'Terry','Palin': 'Michael',
}
删除不存在的报错>>> del pythons['Marx']
Traceback (most recent call last):
File"", line 1, in
del pythons['Marx']
KeyError:'Marx'
>>> del pythons['Idle']>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Jones': 'Terry', 'Palin': 'Michael'}>>>
3.4.6 使用 clear() 删除所有元素
使用 clear() ,或者给字典变量重新赋值一个空字典( {} )可以将字典中所有元素删除:
>>>pythons
{'Chapman': 'Graham', 'Cleese': 'John', 'Jones': 'Terry', 'Palin': 'Michael'}>>>pythons.clear()>>>pythons
{}
3.4.7 使用 in 判断是否存在
如果你希望判断某一个键是否存在于一个字典中,可以使用 in 。
>>> pythons = {'Chapman': 'Graham', 'Cleese': 'John','Jones': 'Terry', 'Palin': 'Michael'}>>> 'Chapman' inpythons
True>>> 'Gilliam' inpythons
False
3.4.8 使用 [key] 获取元素
这是对字典最常进行的操作,只需指定字典名和键即可获得对应的值:
>>> pythons = {'Chapman': 'Graham', 'Cleese': 'John','Jones': 'Terry', 'Palin': 'Michael'}>>> pythons['Cleese']'John'如果字典中不包含指定的键,会产生一个异常>>> pythons['Marx']
Traceback (most recent call last):
File"", line 1, in pythons['Marx']
KeyError:'Marx'有两种方法可以避免这种情况的发生。第一种是在访问前通过in测试键是否存在,就像
在上一小节看到的一样:>>> 'Marx' inpythons
False
另一种方法是使用字典函数 get() 。你需要指定字典名,键以及一个可选值。如果键存在,
会得到与之对应的值:>>> pythons.get('Cleese')'John'反之,若键不存在,如果你指定了可选值,那么 get() 函数将返回这个可选值:>>> pythons.get('Marx', 'Not a Python')'Not a Python'否则,会得到 None (在交互式解释器中什么也不会显示):>>> pythons.get('Marx')
3.4.9 使用 keys() 获取所有键
使用 keys() 可以获得字典中的所有键
>>> signals = {'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera'}>>>signals.keys()
dict_keys(['green', 'yellow', 'red'])
在 Python 2 里, keys() 会返回一个列表,而在 Python 3 中则会返回 dict_
keys() ,它是键的迭代形式。这种返回形式对于大型的字典非常有用,因为
它不需要时间和空间来创建返回的列表。有时你需要的可能就是一个完整的
列表,但在 Python 3 中,你只能自己调用 list() 将 dict_keys 转换为列表
类型。
>>>list(signals.keys())
['green', 'yellow', 'red']
3.4.10 使用 values() 获取所有值
>>>list( signals.values() )
['go', 'go faster', 'smile for the camera']
3.4.11 使用 items() 获取所有键值对
使用 items() 函数可以获取字典中所有的键值对:
>>>list( signals.items() )
[('green', 'go'), ('yellow', 'go faster'), ('red', 'smile for the camera')]>>>
3.4.12 使用 = 赋值,使用 copy() 复制
与列表一样,对字典内容进行的修改会反映到所有与之相关联的变量名上:
>>> signals = {'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera'}>>> save_signals =signals>>> signals['blue'] = 'confuse everyone'
>>>save_signals
{'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera', 'blue': 'confuse everyone'}
若想避免这种情况,可以使用 copy() 将字典复制到一个新的字典中
>>> signals = {'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera'}>>> original_signals =signals.copy()>>> signals['blue'] = 'confuse everyone'
>>>signals
{'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera', 'blue': 'confuse everyone'}>>>original_signals
{'green': 'go', 'yellow': 'go faster', 'red': 'smile for the camera'}>>>
---------------------------------------------------------------
5.5.1 使用 setdefault() 和 defaultdict() 处理缺失的键
读取字典中不存在的键的值会抛出异常。使用字典函数 get() 返回一个默认值会避免异常
发生。函数 setdefault() 类似于 get() , 但当键不存在时它会在字典中添加一项:
In [76]: dic = {'cat': 1, 'dog': 2}
In [77]: dic.get('cat')
Out[77]: 1In [78]: dic.get('cat', 3)
Out[78]: 1In [79]: dic.get('pig', 5)
Out[79]: 5In [80]: dic
Out[80]: {'cat': 1, 'dog': 2}'''如果键不在字典中,新的默认值会被添加进去'''In [81]: a = dic.setdefault('pig', 5)
In [82]: a
Out[82]: 5In [83]: dic
Out[83]: {'cat': 1, 'dog': 2, 'pig': 5}'''如果试图把一个不同的默认值赋给已经存在的键,不会改变原来的值,仍将返回初始值'''In [84]: b = dic.setdefault('dog', 6)
In [85]: b
Out[85]: 2In [86]: dic
Out[86]: {'cat': 1, 'dog': 2, 'pig': 5}
defaultdict() 也有同样的用法,但是在创建字典时,对每个新的键都会指定默认值。它的
参数是一个函数。在本例中,把函数 int 作为参数传入,会按照 int() 调用,返回整数 0 :
In [86]: dic
Out[86]: {'cat': 1, 'dog': 2, 'pig': 5}
In [87]: from collections importdefaultdict
In [88]: periodic_table =defaultdict(int)
In [89]: periodic_table['cat'] = 1In [90]: periodic_table['dog']
Out[90]: 0
In [91]: periodic_table
Out[91]: defaultdict(int, {'cat': 1, 'dog': 0})'''函数 defaultdict() 的参数是一个函数,它返回赋给缺失键的值。在下面的例子中, no_
idea() 在需要时会被执行,返回一个值:'''In [92]: from collections importdefaultdict
In [93]: defno_idea():
...:return 'Huh?'...:
In [94]: animals =defaultdict(no_idea)
In [95]: animals['A'] = 'cat'In [96]: animals['B'] = 'dog'In [97]: animals['a']
Out[97]: 'Huh?'In [98]: animals['A']
Out[98]: 'cat'In [99]: animals
Out[99]:
defaultdict(,
{'A': 'cat', 'B': 'dog', 'a': 'Huh?'})
同样,可以使用函数 int() 、 list() 或者 dict() 返回默认空的值: int() 返回 0 , list()
返回空列表( [] ), dict() 返回空字典( {} )。如果你删掉该函数参数,新键的初始值会被
设置为 None 。
_______________________________________________________________
顺便提一下,也可以使用 lambda 来定义你的默认值函数:
In [100]: animals = defaultdict(lambda: 'Huh?')
In [101]: animals['E']
Out[101]: 'Huh?'
_______________________________________________________________
使用 int 是一种定义计数器的方式:
In [102]: from collections import defaultdict
In [103]: food_counter = defaultdict(int)
In [104]: for food in ['spam', 'spam', 'eggs', 'spam']:
...: food_counter[food] += 1
...:
In [105]: for food, count in food_counter.items():
...: print(food, count)
...:
spam 3
eggs 1
_______________________________________________________________
3.5 集合
集合就像舍弃了值,仅剩下键的字典一样。键与键之间也不允许重复。如果你仅仅想知道
某一个元素是否存在而不关心其他的,使用集合是个非常好的选择。如果需要为键附加其
他信息的话,建议使用字典。
可以仔细看看图 3-1,它展示了我们对于集合进行的最基本的操作——交和并
3.5.1 使用 set() 创建集合
你可以使用 set() 函数创建一个集合,或者用大括号将一系列以逗号隔开的值包裹起来,
>>> empty_set =set()>>>empty_set
set()>>> even_numbers = {0, 2, 4, 6, 8}>>>even_numbers
{0,2, 4, 6, 8}>>> odd_numbers = {1, 3, 5, 7, 9}>>>odd_numbers
{1, 3, 5, 7, 9}
3.5.2 使用 set() 将其他类型转换为集合
你可以利用已有列表、字符串、元组或字典的内容来创建集合,其中重复的值会被丢弃
>>> set("letters")
{'e', 't', 'r', 's', 'l'}
注意,上面得到的集合中仅含有一个'e' 和一个 't' ,尽管字符串 'letters'里各自包含
两个。
用列表建立集合>>> set( ['Dasher', 'Dancer', 'Prancer', 'Mason-Dixon'] )
{'Dasher', 'Dancer', 'Mason-Dixon', 'Prancer'}
再试试元组>>> set( ('Ummagumma', 'Echoes', 'Atom Heart Mother') )
{'Atom Heart Mother', 'Echoes', 'Ummagumma'}
当字典作为参数传入 set() 函数时,只有键会被使用>>> set( {'apple': 'red', 'orange': 'orange', 'cherry': 'red'} )
{'cherry', 'apple', 'orange'}
3.5.3 使用 in 测试值是否存在
>>> drinks ={'martini': {'vodka', 'vermouth'},'black russian': {'vodka', 'kahlua'},'white russian': {'cream', 'kahlua', 'vodka'},'manhattan': {'rye', 'vermouth', 'bitters'},'screwdriver': {'orange juice', 'vodka'}
}>>> for name, contents indrinks.items():if 'vodka' incontents:print(name)
martini
black russian
white russian
screwdriver
3.5.4 合并及运算符
>>> for name, contents indrinks.items():if contents & {'vermouth', 'orange juice'}:print(name)
martini
manhattan
screwdriver>>> contents & {'vermouth', 'orange juice'}
{'orange juice'}
可以通过使用特殊标点符号 & 或者集合函数 intersection() 获取集合的交集
>>> a &b
{2}>>>a.intersection(b)
{2}
使用 | 或者 union() 函数来获取集合的并集(至少出现在一个集合中的元素)
>>> a |b
{1, 2, 3}>>>a.union(b)
{1, 2, 3}
使用字符 - 或者 difference() 可以获得两个集合的差集(出现在第一个集合但不出现在第
二个集合)
>>> a -b
{1}>>>a.difference(b)
{1}
使用 ^ 或者 symmetric_difference() 可以获得两个集合的异或集(仅在两个集合中出现一次)
>>> a ^b
{1, 3}>>>a.symmetric_difference(b)
{1, 3}
使用 <= 或者 issubset() 可以判断一个集合是否是另一个集合的子集(第一个集合的所有
元素都出现在第二个集合中)
>>> a <=b
False>>>a.issubset(b)
False
一个集合是它本身的子集吗?答案为:是的。
>>>a.issubset(a)
True>>> a <=a
True
当第二个集合包含所有第一个集合的元素,且仍包含其他元素时,我们称第一个集合为第
二个集合的真子集。使用 < 可以进行判断:
>>> a
False
超集与子集正好相反(第二个集合的所有元素都出现在第一个集合中),使用 >= 或者
issuperset() 可以进行判断:
>>> a >=b
False>>>a.issuperset(b)
False
一个集合是它本身的超集:
>>> a >=a
True>>>a.issuperset(a)
True
最后,使用 > 可以找到一个集合的真超集(第一个集合包含第二个集合的所有元素且还包
含其他元素):
>>> a >b
False
一个集合并不是它本身的真超集:
>>> a >a
False
3.6 比较几种数据结构
回顾一下,我们学会了使用方括号( [] )创建列表,使用逗号创建元组,使用花括号( {} )
创建字典。在每一种类型中,都可以通过方括号对单个元素进行访问
>>> marx_list = ['Groucho', 'Chico', 'Harpo']>>> marx_tuple = 'Groucho', 'Chico', 'Harpo'
>>> marx_dict = {'Groucho': 'banjo', 'Chico': 'piano', 'Harpo': 'harp'}>>> marx_list[2]'Harpo'
>>> marx_tuple[2]'Harpo'
>>> marx_dict['Harpo']'harp'
3.7 建立大型数据结构
我们从最简单的布尔型、数字、字符串型开始学习,到目前为止,学习到了列表、元组、
集合以及字典等数据结构。你可以将这些内置的数据结构自由地组合成更大、更复杂的结
构。
>>> marxes = ['Groucho', 'Chico', 'Harpo']>>> pythons = ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin']>>> stooges = ['Moe', 'Curly', 'Larry']
可以把上面每一个列表当作一个元素,并建立一个元组>>> tuple_of_lists =marxes, pythons, stooges>>>tuple_of_lists
(['Groucho', 'Chico', 'Harpo'], ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin'], ['Moe', 'Curly', 'Larry'])
可以创建一个包含上面三个列表的列表>>> list_of_lists =[marxes, pythons, stooges]>>>list_of_lists
[['Groucho', 'Chico', 'Harpo'], ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin'], ['Moe', 'Curly', 'Larry']]
还可以创建以这三个列表为值的字典>>> dict_of_lists = {'Marxes': marxes, 'Pythons': pythons, 'Stooges': stooges}>>>dict_of_lists
{'Marxes': ['Groucho', 'Chico', 'Harpo'], 'Pythons': ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin'], 'Stooges': ['Moe', 'Curly', 'Larry']}>>>
在创建自定义数据结构的过程中,唯一的限制来自于这些内置数据类型本身。比如,字典
的键必须为不可变对象,因此列表、字典以及集合都不能作为字典的键,但元组 和 字符串 可以作为
字典的键。举个例子,我们可以通过 GPS 坐标(纬度,经度,海拔;B.6 节可以看到更多
与地图有关的例子)定位感兴趣的位置:
>>> houses ={
(44.79, -93.14, 285): 'My House',
(38.89, -77.03, 13): 'The White House'}>>>houses
{(44.79, -93.14, 285): 'My House', (38.89, -77.03, 13): 'The White House'}>>>
5.5.2 使用 Counter() 计数
说起计数器,标准库有一个计数器,它可以胜任之前或者更多示例所做的工作:
In [1]: fromcollections import Counter
In [2]: breakfast = ['spam', 'spam', 'eggs', 'spam']
In [3]: breakfast_counter =Counter(breakfast)
In [4]: breakfast_counter
Out[4]: Counter({'spam': 3, 'eggs': 1})'''函数 most_common() 以降序返回所有元素,或者如果给定一个数字,会返回该数字前的的
元素'''In [5]: breakfast_counter.most_common()
Out[5]: [('spam', 3), ('eggs', 1)]
In [6]: breakfast_counter.most_common(1)
Out[6]: [('spam', 3)]
'''新建一个列表 lunch 和一个计数器 lunch_counter :'''In [8]: lunch = ['eggs', 'eggs', 'bacon']
In [9]: lunch_counter =Counter(lunch)
In [10]: lunch_counter
Out[10]: Counter({'eggs': 2, 'bacon': 1})'''第一种组合计数器的方式是使用 + :'''In [11]: breakfast_counter +lunch_counter
Out[11]: Counter({'spam': 3, 'eggs': 3, 'bacon': 1})'''从一个计数器去掉另一个,可以使用 -'''In [12]: breakfast_counter -lunch_counter
Out[12]: Counter({'spam': 3})'''和第 4 章中的集合类似,可以使用交集运算符 & 得到二者共有的项'''In [13]: breakfast_counter &lunch_counter
Out[13]: Counter({'eggs': 1})'''最后,使用并集运算符 | 得到所有元素:'''In [14]: breakfast_counter |lunch_counter
Out[14]: Counter({'spam': 3, 'eggs': 2, 'bacon': 1})
5.5.3 使用有序字典 OrderedDict() 按键排序
在前面几章的代码示例中可以看出,一个字典中键的顺序是不可预知的:你可以按照顺序
添加键 a 、 b 和 c ,但函数 keys() 可能返回 c 、 a 和 b 。下面是第 1 章用过的一个例子:
In [15]: quotes ={
...:'Moe': 'A wise guy, huh?',
...:'Larry': 'Ow!',
...:'Curly': 'Nyuk nyuk!',
...: }
In [16]: for stooge inquotes:
...:print(stooge)
...:
Moe
Larry
Curly
有序字典 OrderedDict() 记忆字典键添加的顺序,然后从一个迭代器按照相同的顺序返
回。 试着用元组(键,值)创建一个有序字典:
In [18]: from collections importOrderedDict
In [19]: quotes =OrderedDict([
...: ('Moe', 'A wise guy, huh?'),
...: ('Larry', 'Ow!'),
...: ('Curly', 'Nyuk nyuk!'),
...: ])
In [20]: for stooge inquotes:
...:print(stooge)
...:
Moe
Larry
Curly
5.5.4 双端队列:栈+队列
deque 是一种双端队列,同时具有栈和队列的特征。它可以从序列的任何一端添加和删除
项。现在,我们从一个词的两端扫向中间,判断是否为回文。函数 popleft() 去掉最左边
的项并返回该项, pop() 去掉最右边的项并返回该项。从两边一直向中间扫描,只要两端
的字符匹配,一直弹出直到到达中间
In [23]: defpalindrome(word):
...:from collections importdeque
...: dq=deque(word)
...:while len(dq) > 1:
...:if dq.popleft() !=dq.pop():
...:returnFalse
...:returnTrue
...:
In [24]: palindrome('a')
Out[24]: True
In [25]: palindrome('racecar')
Out[25]: True
In [26]: palindrome('')
Out[26]: True
In [27]: palindrome('radar')
Out[27]: True
In [28]: palindrome('abccba')
Out[28]: True
In [29]: palindrome('abccbc')
Out[29]: False
这里把判断回文作为双端队列的一个简单说明。如果想要写一个快速的判断回文的程
序,只需要把字符串反转和原字符串进行比较。Python 没有对字符串进行反转的函数
reverse() ,但还是可以利用反向切片的方式进行反转,如下所示:
In [30]: defanother_palindrome(word):
...:return word == word[::-1]
...:
In [31]: another_palindrome('radar')
Out[31]: True
In [32]: another_palindrome('abccbc')
Out[32]: False
5.5.6 使用 pprint() 友好输出
我们见到的所有示例都用 print() (或者在交互式解释器中用变量名)打印输出。有时输
出结果的可读性较差。我们需要一个友好输出函数,比如 pprint() :
In [36]: from pprint importpprint
In [37]: quotes =OrderedDict([
...: ('Moe', 'A wise guy, huh?'),
...: ('Larry', 'Ow!'),
...: ('Curly', 'Nyuk nyuk!'),
...: ])'''普通的 print() 直接列出所有结果'''In [38]: print(quotes)
OrderedDict([('Moe', 'A wise guy, huh?'), ('Larry', 'Ow!'), ('Curly', 'Nyuk nyuk!')])'''但是, pprint() 尽量排列输出元素从而增加可读性:'''In [39]: pprint(quotes)
OrderedDict([('Moe', 'A wise guy, huh?'),
('Larry', 'Ow!'),
('Curly', 'Nyuk nyuk!')])
python集合和列表、安从小到大的顺序组合成一个字典_第3章 Python容器:列表、元组、字典与集合...相关推荐
- python 按从小到大的顺序组合成一个字典_将Python字典排列组合成字典列表
鉴于字典看起来像这样: { 'Color': ['Red', 'Yellow'], 'Size': ['Small', 'Medium', 'Large'] } 如何创建一个结合了第一个字典键的各种值 ...
- python 按从小到大的顺序组合成一个字典_Python实现字典排序、按照list中字典的某个key排序的方法示例...
本文实例讲述了python实现字典排序.按照list中字典的某个key排序的方法.分享给大家供大家参考,具体如下: 1.给字典按照value按照从大到小排序 排序 dict = {'a':21, 'b ...
- pb 修改数据窗口种指定字段位置_第三章 Python数据类型 容器
数据类型 容器 Python中的数据包括元素和容器两大类: 元素: 1.数字 包括整数.浮点数. 1.1整数 1.2浮点数 2.布尔类型 3.删除数字对象引用,例如: 4.数字类型转换 5.数学函数 ...
- python语言用什么来表明每行代码的层次关系_《计算机二级Python语言程序设计考试》第2章: Python语言基本语法元素...
注明:本系列课程专为全国计算机等级考试二级 Python 语言程序设计考试服务 目录 考纲考点 程序的基本语法元素:程序的格式框架.缩进.注释.变量.命名.保留字.数据类型.赋值语句.引用 基本输入输 ...
- python123第四章第五题_第五章 Python 函数
第1章 为什么要使用函数 #1.代码的组织结构不清晰,可读性差 #2.遇到重复的功能只能重复编写实现代码,代码冗余 #3.功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 ...
- python中字符串类型的encode()方法_第五章 Python字符串常用方法详解
5.1 Python字符串拼接(包含字符串拼接数字) 在 Python中拼接(连接)字符串很简单,可以直接将两个字符串紧挨着写在一起,具体格式为: strname = "str1" ...
- python是一种跨平台开源免费的高级动态编程语言吗_第1章 管中窥豹:Python概述免费阅读_Python程序设计开发宝典免费全文_百度阅读...
1.1 Python是这样一种语言 有不少人说Python是一种"大蟒蛇语言".虽然在英语中Python确实有大蟒蛇的意思,但Python语言和大蟒蛇却没有任何关系.Python语 ...
- Python zip() 函数--多个迭代器取元素组合成一个新的迭代器
目录 Python3 元组 描述 语法 实例 1.当zip()函数中只有一个参数时 2.当zip()函数有两个参数时 3.zip()函数的应用 Python3 元组 Python 的元组与列表类似,不 ...
- python基础教程pdf刘浪_《Python基础教程(第3版)》 PDF高清完整版_初学者如何学习Python...
<Python基础教程(第3版)> PDF高清完整版 初学者如何学习Python 内容简介 本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基 ...
最新文章
- klock 分布式锁重大更新
- 4.从单应矩阵中分离得到内参和外参(需要拍摄n=3张标定图片)
- Freemarker的Null处理
- object-c中的bool
- 遇到个鬼,在WIN08的DELL R710上安装CENTOS 63,无法格式化以前的硬盘分区,安装无法进行下去。...
- 分布式数据库——TiDB的介绍和基本原理
- NetCore + SignalR 实现日志消息推送
- java跳转画面后画面白了_如何跳转指定页面后再次跳转到另一页面或原来的页面...
- netflix的准实验面临的主要挑战
- [js] 使用for-in语句能保证遍历对象的顺序吗?如果不能那为什么?如果可以那又如何保证?
- [十二省联考2019]字符串问题 后缀自动机 + 拓扑排序 + 最长路 + 倍增
- Unity Using Interception and Policy Injection
- 如何取得GridView被隐藏列的值
- logstash+elasticsearch +kibana 日志管理系统
- 制作自启动的MSDN简体中文版和英文版win98ISO镜像
- 高通QFIL9008端口刷机报错问题
- JAVA|什么是Sdkman
- 分布式环境下对部分热数据(如redis热key,热请求)进行探测,并对探测结果及时同步到各个client实例的JVM内存的方案简述
- 用水流的概念来玩硬件(三)----LDO与DCDC电源电路
- spring接管mybatis