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容器:列表、元组、字典与集合...相关推荐

  1. python 按从小到大的顺序组合成一个字典_将Python字典排列组合成字典列表

    鉴于字典看起来像这样: { 'Color': ['Red', 'Yellow'], 'Size': ['Small', 'Medium', 'Large'] } 如何创建一个结合了第一个字典键的各种值 ...

  2. python 按从小到大的顺序组合成一个字典_Python实现字典排序、按照list中字典的某个key排序的方法示例...

    本文实例讲述了python实现字典排序.按照list中字典的某个key排序的方法.分享给大家供大家参考,具体如下: 1.给字典按照value按照从大到小排序 排序 dict = {'a':21, 'b ...

  3. pb 修改数据窗口种指定字段位置_第三章 Python数据类型 容器

    数据类型 容器 Python中的数据包括元素和容器两大类: 元素: 1.数字 包括整数.浮点数. 1.1整数 1.2浮点数 2.布尔类型 3.删除数字对象引用,例如: 4.数字类型转换 5.数学函数 ...

  4. python语言用什么来表明每行代码的层次关系_《计算机二级Python语言程序设计考试》第2章: Python语言基本语法元素...

    注明:本系列课程专为全国计算机等级考试二级 Python 语言程序设计考试服务 目录 考纲考点 程序的基本语法元素:程序的格式框架.缩进.注释.变量.命名.保留字.数据类型.赋值语句.引用 基本输入输 ...

  5. python123第四章第五题_第五章 Python 函数

    第1章 为什么要使用函数 #1.代码的组织结构不清晰,可读性差 #2.遇到重复的功能只能重复编写实现代码,代码冗余 #3.功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 ...

  6. python中字符串类型的encode()方法_第五章 Python字符串常用方法详解

    5.1 Python字符串拼接(包含字符串拼接数字) 在 Python中拼接(连接)字符串很简单,可以直接将两个字符串紧挨着写在一起,具体格式为: strname = "str1" ...

  7. python是一种跨平台开源免费的高级动态编程语言吗_第1章 管中窥豹:Python概述免费阅读_Python程序设计开发宝典免费全文_百度阅读...

    1.1 Python是这样一种语言 有不少人说Python是一种"大蟒蛇语言".虽然在英语中Python确实有大蟒蛇的意思,但Python语言和大蟒蛇却没有任何关系.Python语 ...

  8. Python zip() 函数--多个迭代器取元素组合成一个新的迭代器

    目录 Python3 元组 描述 语法 实例 1.当zip()函数中只有一个参数时 2.当zip()函数有两个参数时 3.zip()函数的应用 Python3 元组 Python 的元组与列表类似,不 ...

  9. python基础教程pdf刘浪_《Python基础教程(第3版)》 PDF高清完整版_初学者如何学习Python...

    <Python基础教程(第3版)> PDF高清完整版 初学者如何学习Python 内容简介 本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基 ...

最新文章

  1. klock 分布式锁重大更新
  2. 4.从单应矩阵中分离得到内参和外参(需要拍摄n=3张标定图片)
  3. Freemarker的Null处理
  4. object-c中的bool
  5. 遇到个鬼,在WIN08的DELL R710上安装CENTOS 63,无法格式化以前的硬盘分区,安装无法进行下去。...
  6. 分布式数据库——TiDB的介绍和基本原理
  7. NetCore + SignalR 实现日志消息推送
  8. java跳转画面后画面白了_如何跳转指定页面后再次跳转到另一页面或原来的页面...
  9. netflix的准实验面临的主要挑战
  10. [js] 使用for-in语句能保证遍历对象的顺序吗?如果不能那为什么?如果可以那又如何保证?
  11. [十二省联考2019]字符串问题 后缀自动机 + 拓扑排序 + 最长路 + 倍增
  12. Unity Using Interception and Policy Injection
  13. 如何取得GridView被隐藏列的值
  14. logstash+elasticsearch +kibana 日志管理系统
  15. 制作自启动的MSDN简体中文版和英文版win98ISO镜像
  16. 高通QFIL9008端口刷机报错问题
  17. JAVA|什么是Sdkman
  18. 分布式环境下对部分热数据(如redis热key,热请求)进行探测,并对探测结果及时同步到各个client实例的JVM内存的方案简述
  19. 用水流的概念来玩硬件(三)----LDO与DCDC电源电路
  20. spring接管mybatis

热门文章

  1. 华为matebook13进入Bios,重装系统,切换启动顺序,选择U盘启动
  2. 情感识别相关数据集总结
  3. python复制文件夹shutil.copytree
  4. Druid监控页面配置用户密码、去除Ad
  5. mysql级联删除_每天学一点学点MySQL数据库之第二节
  6. win10中安装JDK8以及环境配置
  7. 数据分析总结四:可视化与数据分析
  8. 《卸甲笔记》-基础语法对比
  9. 人体动作捕捉-坐标转换
  10. 卡特兰数Catalan