十、列表
有时候可以把一堆东西存储在一起,放在某种“组”或者“集合”中,这可能很有用。这样一来,就可以一次对整个集合做某些处理,也能更容易地记录一组东西。有一类集合叫做列表(list),另一类叫做字典(dictionary)。
列表
列表中的单个元素就叫做项或者元素(item)。
family = ['Mom', 'Dad', 'Junior', 'Baby']
luckyNumbers = [2, 7, 14, 26, 30]
就像创建任何其他变量一样,创建列表也是要为它赋某个值,如前面对 luckyNumbers
的赋值。另外还可以创建一个空的列表,如:newList = []
中括号没有任何元素,所以这个列表是空的。很多情况下,我们无法提前知道列表中会有些什么。我们不知道其中会有多少元素,也不知道这些元素是什么,只知道将会用一个列表来保存这些内容。有了空列表后,程序就可以向这个列表中增加元素。
friends = []
friends.append('David')
print(friends)
>>> ['David']
friends.append('Mary')
print(friends)
>>>['David', 'Mary']
记住,向列表增加元素之前,必须先创建列表(可以是空列表,也可以非空)。这就像在做一个蛋糕:不能直接把各种配料倒在一起,而是先将配料倒人碗中,不然肯定会弄得到处都是!
列表可以包含 Python 能存储的任何类型的数据,这包括数字、字符串、对象,甚至可以包含其他列表。并不要求列表中的元素是同种类型或同一种东西。这说明,一个列表中可以同时包含不同类型,例如数字和字符串,可能像这样:
my_list = [5, 10, 23.76, 'Hello', myTeacher, 7, another_list]
索引
下面用一些简单的内容建立一个新列表,比如字母表中的字母,这样我们在学习列表时就能更容易地了解做了些什么。在交互模式中键入下面的代码:
>>> letters = ['a', 'b', 'c', 'd', 'e']
>>> print(letters[0])
a
>>> print(letters[3])
d
可以按元素的索引(index)号从列表获取单个元素。列表索引从 0
开始,所以这个列表中的第一项就是 letters[0]
分片
还可以使用索引从列表一次获取多个元素。这叫做列表分片(slicing)。
>>> print(letters[1:4])
['b', 'c', 'd']
分片获取元素时,会从第一个索引开始,不过在达到第二个索引之前停止。正是因为这个原因,前面的例子中我们只取回 3 项, 而不是 4 项。要记住这一点,一种方法就是牢记取回的项数总是两个索引数之差(4 – 1 = 3,所以取回 3 项)。
对列表分片时取回的是另一个(通常更小的)列表。这个更小的列表称为原列表的一个分片(slice)。原来的列表并没有改变。这个分片是原列表的部分副本(copy)。
>>> print(letters[:2])
['a', 'b']
>>> print(letters[2:])
['c', 'd', 'e']
>>> print(letters[:])
['a', 'b', 'c', 'd', 'e']
>>> print(letters[3:1:-1]) //结合 range(3, 1, -1) 预判输出
修改元素
可以使用索引来修改某个列表元素:
>>> print(letters)
['a', 'b', 'c', 'd', 'e']
>>> letters[2] = 'z'
>>> print(letters)
['a', 'b', 'z', 'd', 'e']
增加元素
append()
向列表末尾增加一个元素。-
extend()
向列表末尾增加多个元素。 insert()
在列表中的某个位置增加一个元素:- 不一定非得在列表末尾。
- 你可以告诉它要在哪里增加元素。
```python
letters.append(‘g’) print(letters) [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘n’, ‘g’]
letters.extend([‘p’, ‘q’, ‘r’]) print(letters) [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘n’, ‘g’, ‘p’, ‘q’, ‘r’]
letters.insert(2, ‘z’) print(letters) [‘a’, ‘b’, ‘z’, ‘c’, ‘d’, ‘e’, ‘n’, ‘g’, ‘p’, ‘q’, ‘r’] ```
删除元素
remove()
会从列表中删除你选择的元素,把它丢掉。del
利用索引从列表中删除元素。pop()
从列表中取出最后一个元素交给你。 ```pythonletters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] letters.remove(‘c’) print(letters) [‘a’, ‘b’, ‘d’, ‘e’]
letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] del letters[3] print(letters) [‘a’, ‘b’, ‘c’, ‘e’]
letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] lastLetter = letters.pop() print(letters) [‘a’, ‘b’, ‘c’, ‘d’] print(lastLetter) e
letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] second = letters.pop(1) #(索引 1) print(second) b print(letters) [‘a’, ‘c’, ‘d’, ‘e’] ```
用 remove()
删除,你不需要知道这个元素在列表中的具体位置,只需要知道它确实在列表中(可以是任何位置)。如果你想删除的东西根本不在列表中,就会得到错误消息。
括号里没有提供参数时,pop()
会返回最后一个元素,并把它从列表中删除。如果在括号里放入一个数,pop(n)
会给出这个索引位置上的元素,而且会把它从列表中删除。
查找元素
- 查找元素是否在列表中。
- 查找元素在列表中的哪个位置(元素的索引)。
in 关键字
要找出某个元素是否在列表中,可以使用 in
关键字,例如:
if 'a' in letters:
print("found 'a' in letters")
else:
print("didn't find 'a' in letters")
if 'k' in letters: #结合使用 in 和 remove
letters.remove('k')
'a' in letters
部分是一个布尔或逻辑表达式。如果a在这个列表中,它会返回值 True,否则返回 False。
查找索引
为了找出一个元素位于列表中的什么位置,可以使用 index()
方法,如下:
>>> letters = ['a', 'b', 'c', 'd', 'e']
>>> print(letters.index('d'))
3
所以我们知道 d
的索引是 3
,这说明它是列表中的第 4
个元素。
排序
列表是一种有顺序(ordered)的集合。这说明列表中的元素有某种顺序,每个元素都有一个位置,也就是它的索引。一旦以某种顺序将元素放在列表中,它们就会保持这种顺序,除非用 insert()
、append()
、remove()
或 pop()
改变列表。不过这个顺序可能不是你真正想要的顺序。
>>> letters = ['d', 'a', 'e', 'c', 'b']
>>> print(letters)
['d', 'a', 'e', 'c', 'b']
>>> letters.sort()
>>> print(letters)
['a', 'b', 'c', 'd', 'e']
sort()
会自动按字母顺序对字符串从小到大排序,如果是数字,就会按数字顺序从小到大排序。sort()
会在原地修改列表。这说明它会改变你提供的原始列表,而不是创建一个新的有序列表。
逆序
让一个列表按逆序排序有两种方法。一种方法是先按正常方式对列表排序,然后对这个有序列表完成逆置(reverse),如下:
>>> letters = ['d', 'a', 'e', 'c', 'b']
>>> letters.sort()
>>> print(letters)
['a', 'b', 'c', 'd', 'e']
>>> letters.reverse()
>>> print(letters)
['e', 'd', 'c', 'b', 'a']
另一种方法是向 sort() 增加了一个参数,直接让它按降序排序(从大到小):
>>> letters = ['d', 'a', 'e', 'c', 'b']
>>> letters.sort(reverse = True)
>>> print(letters)
['e', 'd', 'c', 'b', 'a']
如果希望保留原来的顺序,而对列表的副本进行排序,可以使用分片记法建立副本,也就是与原列表相等的另一个列表:
>>> original_list = ['Tom','James',' Sarah' , 'Fred']
>>> new_list = original_list[:]
>>> new_list.sort()
>>> print(original_list)
['Tom','James','Sarah','Fred']
>>> print new_list
['Fred','James','Sarah','Tom']
sorted()
有一种方法可以得到一个列表的有序副本而不会影响原列表的顺序。Python 提供了一个名为 sorted()
的函数可以完成这个功能。如下:
>>> original = [5, 2, 3, 1, 4]
>>> newer = sorted(original)
>>> prin(original)
[5, 2, 3, 1, 4]
>>> print(newer)
[1, 2, 3, 4, 5]
Matrix 数据表
列表中包含多个元素,
#可以把每个学生的成绩放在一个列表中,像这样:
>>> joeMarks = [55, 63, 77, 81]
>>> tomMarks = [65, 61, 67, 72]
>>> bethMarks = [97, 95, 92, 88]
#或者对应每个课程使用一个列表,如下:
>>> mathMarks = [55, 65, 97]
>>> scienceMarks = [63, 61, 95]
>>> readingMarks = [77, 67, 92]
>>> spellingMarks = [81, 72, 88]
#为成绩建立一个数据结构
>>> classMarks = [joeMarks, tomMarks, bethMarks]
>>> print(classMarks)
[[55, 63, 77, 81], [65, 61, 67, 72], [97, 95, 92, 88]] #list of list
>>> print(classMarks[0])
[55, 63, 77, 81]
>>> print(classMarks[0][2])
77
元组(tuple)
简单的说,就是不可改变的数组,用小括号表示:(a, b, c)
,没有增删改操作。因为 tuple
不可变,所以代码更安全。如果可能,能用 tuple
代替 list
就尽量用 tuple
。
来看一个“可变的”tuple:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
tuple
所谓的“不变”是说,tuple
的每个元素,指向永远不变。即指向 ‘a’,就不能改成指向 ‘b’,指向一个 list
,就不能改成指向其他对象,但指向的这个 list
本身是可变的!理解了“指向不变”后,要创建一个内容也不变的 tuple
怎么做?那就必须保证 tuple
的每一个元素本身也不能变。
只有1个元素的 tuple 定义时必须加一个逗号 ,
,来消除歧义:
>>> t = (1,)
>>> t
(1,)
解压
t = (1, 10.31, ('OK', 'python'))
(a, b, (c, d)) = t
print(a, b, c, d)
# 1 10.31 OK python
如果只想要元组其中几个元素,用通配符「*」,英文叫 wildcard
,在计算机语言中代表一个或多个元素。
t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print(a, b, c)
# 1 2 5
print(rest)
# [3, 4]
#---------------------------------
a, b, *_ = t
print(a, b)
# 1 2
Revison
- 列表是什么。
- 如何向列表中增加元素。
- 如何从列表删除元素。
- 何确定列表是否包含某个值。
- 如何对列表排序。
- 如何建立列表的副本。
- 元组。
- 双重列表。
测试题
- 向列表增加元素有哪些方法?
- 从列表删除元素有哪些方法?
- 要得到一个列表的有序副本,但又不能改变原来的列表,有哪两种方法?
- 怎样得出某个值是否在列表中?
- 如何确定某个值在列表中的位置?
- 什么是元组?
- 如何建立双重列表?
- 如何从一个双重列表中得到一个值?
动手试一试
- 写一个程序,让用户提供 5 个名字。程序要把这 5 个名字保存在一个列表中,最后打印出来。就像这样: ```shell Enter 5 names: Tony Paul Nick Michel Kevin
The names are Tony Paul Nick Michel Kevin
- 修改第 1 题的程序,要求不仅显示原来的名字列表,还要显示出排序后的列表。
- 修改第 1 题的程序,要求只显示用户键入的第 3 个名字,就像这样:
```shell
The third name you entered is: Nick
- 修改第 1 题的程序,让用户替换其中一个名字。用户应该能选择要替换哪个名字,然后键入新名字。最后显示这个新的列表: ```shell Enter 5 names: Tony Paul Nick Michel Kevin
The names are Tony Paul Nick Michel Kevin
Replace one name. Which one? (1-5): 4 New name: Peter
The names are Tony Paul Nick Peter Kevin
<a name="rB8wg"></a>
# 十一、字典
Python 列表是一种将元素组织在一起的方式。在编程中,经常会以另一种方式组织元素,将某个值和另一个值关联起来。这种组织方式就像电话通讯录将姓名和电话号码关联起来,也像字典将单词和它们的含义关联起来。
Python 字典(dictionary)是一种将两个东西关联在一起的方式。被关联在一起的两个东西分别称为键(key)和值(value)。字典中的每个项(item)或条目(entry)都有一个键和一个值,它们合起来被称为键值对(key-value pair)。一个字典就是一些键值对的集合。
一个简单的例子就是电话通讯录。假设你想保存朋友们的电话号码。你会使用他们的姓名去查找他们的号码。这个姓名就是“键”,即你会用它来查找信息,而电话号码就是“值”,即你要查找的信息。
```python
>>> phoneNumbers = {}
>>> phoneNumbers["John"] = "555-1234"
>>> print(phoneNumbers)
{'John': '555-1234'}
>>> phoneNumbers = {"John": "555-1234"}
>>> phoneNumbers["Mary"] = '555-6789'
>>> phoneNumbers["Bob"] = '444-4321'
>>> phoneNumbers["Jenny] = '867-5309'
>>> print(phoneNumbers)
{'Bob': '444-4321','John': '1555-1234','Mary': '555-67891', 'Jenny': '1867-53091'}
>>> print(phoneNumbers["Mary"])
'555-6789'
>>> print(phoneNumbers.keys())
['Bob', 'John', 'Mary', 'Jenny']
>>> print(phoneNumbers.values())
['444-4321', '555-1234', '555-6789', '867-5309']
for key in sorted(phoneNumbers.keys()):
print(key, phoneNumbers[key])
Bob 444-4321
Jenny 867-5309
John 555-1234
Mary 555-6789
使用 del
删除一个条目:
>>> del phoneNumbers["John"]
>>> print(phoneNumbers)
{'Bob': '444-4321', 'Mary': '555-6789', 'Jenny': '867-5309'}
使用 clear()
删除所有条目(清空字典)
>>> phoneNumbers.clear()
>>> print(phoneNumbers)
{}
使用 in
确定某个键在字典中是否存在:
>>> phoneNumbers = {'Bob': '444-4321', 'Mary': '555-6789', 'Jenny': '867-5309'}
>>> "Bob" in phoneNumbers
True
>>> "Barb" in phoneNumbers
False
Revison
- 字典。
测试题
- 什么是字典?
- 如何向字典中增加项?
- 怎样使用键去查找一个条目?
动手试一试
- 编写一个字典程序,让用户可以添加单词和定义,然后可以查找这些单词。确保当要查找的单词不存在时,用户能够知晓。运行的时候,它应该是像这样的: ```shell Add or look up a word (a/l)? a Type the word: computer Type the definition: A machine that does very fast math Word added!
Add or look up a word (a/l)? l Type the word: computer A machine that does very fast math
Add or look up a word (a/l)? l Type the word: qwerty That word isn’t in the dictionary yet.
<a name="qOhdM"></a>
# 十二、Set
`set` 和 `dict` 类似,也是一组 `key` 的集合,但不存储 `value`。由于 `key` 不能重复,所以在 `set` 中,没有重复的 `key`。要创建一个 `set`,需要提供一个 `list` 作为输入集合:
```python
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
传入的参数 [1, 2, 3]
是一个 list
,而显示的 {1, 2, 3}
只是告诉你这个 set
内部有 1,2,3 这 3 个元素,显示的顺序也不表示 set
是有序的。。
重复元素在 set
中自动被过滤:
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
set
可以看成数学意义上的无序和无重复元素的集合,因此,两个 set
可以做数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
通过 add(key)
方法可以添加元素到 set
中,可以重复添加,但不会有效果;通过 remove(key)
方法可以删除元素:
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.remove(4)
>>> s
{1, 2, 3}
set
和 dict
的唯一区别仅在于没有存储对应的 value
,但是 set
的原理和 dict
一样,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证 set
内部“不会有重复元素”。试试把 list
放入 set
,看看是否会报错。
测试题
- 创建一个空集合,增加
{‘x’,‘y’,‘z’}
三个元素。 - 求两个集合
{6, 7, 8}
,{7, 8, 9}
中不重复的元素。 - 求
{'A', 'B', 'C'}
中元素在{'B', 'C', 'D'}
中出现的次数。