十、列表

有时候可以把一堆东西存储在一起,放在某种“组”或者“集合”中,这可能很有用。这样一来,就可以一次对整个集合做某些处理,也能更容易地记录一组东西。有一类集合叫做列表(list),另一类叫做字典(dictionary)。

列表

列表中的单个元素就叫做项或者元素(item)。

  1. family = ['Mom', 'Dad', 'Junior', 'Baby']
  2. luckyNumbers = [2, 7, 14, 26, 30]

就像创建任何其他变量一样,创建列表也是要为它赋某个值,如前面对 luckyNumbers 的赋值。另外还可以创建一个空的列表,如:newList = []

中括号没有任何元素,所以这个列表是空的。很多情况下,我们无法提前知道列表中会有些什么。我们不知道其中会有多少元素,也不知道这些元素是什么,只知道将会用一个列表来保存这些内容。有了空列表后,程序就可以向这个列表中增加元素。

  1. friends = []
  2. friends.append('David')
  3. print(friends)
  4. >>> ['David']
  5. friends.append('Mary')
  6. print(friends)
  7. >>>['David', 'Mary']

记住,向列表增加元素之前,必须先创建列表(可以是空列表,也可以非空)。这就像在做一个蛋糕:不能直接把各种配料倒在一起,而是先将配料倒人碗中,不然肯定会弄得到处都是!

列表可以包含 Python 能存储的任何类型的数据,这包括数字、字符串、对象,甚至可以包含其他列表。并不要求列表中的元素是同种类型或同一种东西。这说明,一个列表中可以同时包含不同类型,例如数字和字符串,可能像这样:

  1. my_list = [5, 10, 23.76, 'Hello', myTeacher, 7, another_list]

索引

下面用一些简单的内容建立一个新列表,比如字母表中的字母,这样我们在学习列表时就能更容易地了解做了些什么。在交互模式中键入下面的代码:

  1. >>> letters = ['a', 'b', 'c', 'd', 'e']
  2. >>> print(letters[0])
  3. a
  4. >>> print(letters[3])
  5. d

可以按元素的索引(index)号从列表获取单个元素。列表索引从 0 开始,所以这个列表中的第一项就是 letters[0]

分片

还可以使用索引从列表一次获取多个元素。这叫做列表分片(slicing)。

  1. >>> print(letters[1:4])
  2. ['b', 'c', 'd']

分片获取元素时,会从第一个索引开始,不过在达到第二个索引之前停止。正是因为这个原因,前面的例子中我们只取回 3 项, 而不是 4 项。要记住这一点,一种方法就是牢记取回的项数总是两个索引数之差(4 – 1 = 3,所以取回 3 项)。

对列表分片时取回的是另一个(通常更小的)列表。这个更小的列表称为原列表的一个分片(slice)。原来的列表并没有改变。这个分片是原列表的部分副本(copy)。

  1. >>> print(letters[:2])
  2. ['a', 'b']
  3. >>> print(letters[2:])
  4. ['c', 'd', 'e']
  5. >>> print(letters[:])
  6. ['a', 'b', 'c', 'd', 'e']
  7. >>> print(letters[3:1:-1]) //结合 range(3, 1, -1) 预判输出

修改元素

可以使用索引来修改某个列表元素:

  1. >>> print(letters)
  2. ['a', 'b', 'c', 'd', 'e']
  3. >>> letters[2] = 'z'
  4. >>> print(letters)
  5. ['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() 从列表中取出最后一个元素交给你。 ```python

    letters = [‘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 关键字,例如:

  1. if 'a' in letters:
  2. print("found 'a' in letters")
  3. else:
  4. print("didn't find 'a' in letters")
  5. if 'k' in letters: #结合使用 in 和 remove
  6. letters.remove('k')

'a' in letters 部分是一个布尔或逻辑表达式。如果a在这个列表中,它会返回值 True,否则返回 False。

查找索引

为了找出一个元素位于列表中的什么位置,可以使用 index() 方法,如下:

  1. >>> letters = ['a', 'b', 'c', 'd', 'e']
  2. >>> print(letters.index('d'))
  3. 3

所以我们知道 d 的索引是 3,这说明它是列表中的第 4 个元素。

排序

列表是一种有顺序(ordered)的集合。这说明列表中的元素有某种顺序,每个元素都有一个位置,也就是它的索引。一旦以某种顺序将元素放在列表中,它们就会保持这种顺序,除非用 insert()append()remove()pop() 改变列表。不过这个顺序可能不是你真正想要的顺序。

  1. >>> letters = ['d', 'a', 'e', 'c', 'b']
  2. >>> print(letters)
  3. ['d', 'a', 'e', 'c', 'b']
  4. >>> letters.sort()
  5. >>> print(letters)
  6. ['a', 'b', 'c', 'd', 'e']

sort() 会自动按字母顺序对字符串从小到大排序,如果是数字,就会按数字顺序从小到大排序。sort() 会在原地修改列表。这说明它会改变你提供的原始列表,而不是创建一个新的有序列表。

逆序

让一个列表按逆序排序有两种方法。一种方法是先按正常方式对列表排序,然后对这个有序列表完成逆置(reverse),如下:

  1. >>> letters = ['d', 'a', 'e', 'c', 'b']
  2. >>> letters.sort()
  3. >>> print(letters)
  4. ['a', 'b', 'c', 'd', 'e']
  5. >>> letters.reverse()
  6. >>> print(letters)
  7. ['e', 'd', 'c', 'b', 'a']

另一种方法是向 sort() 增加了一个参数,直接让它按降序排序(从大到小):

  1. >>> letters = ['d', 'a', 'e', 'c', 'b']
  2. >>> letters.sort(reverse = True)
  3. >>> print(letters)
  4. ['e', 'd', 'c', 'b', 'a']

如果希望保留原来的顺序,而对列表的副本进行排序,可以使用分片记法建立副本,也就是与原列表相等的另一个列表:

  1. >>> original_list = ['Tom''James'' Sarah' , 'Fred']
  2. >>> new_list = original_list[:]
  3. >>> new_list.sort()
  4. >>> print(original_list)
  5. ['Tom''James''Sarah''Fred']
  6. >>> print new_list
  7. ['Fred''James''Sarah''Tom']

sorted()

有一种方法可以得到一个列表的有序副本而不会影响原列表的顺序。Python 提供了一个名为 sorted() 的函数可以完成这个功能。如下:

  1. >>> original = [5, 2, 3, 1, 4]
  2. >>> newer = sorted(original)
  3. >>> prin(original)
  4. [5, 2, 3, 1, 4]
  5. >>> print(newer)
  6. [1, 2, 3, 4, 5]

Matrix 数据表

image.png

列表中包含多个元素,

  1. #可以把每个学生的成绩放在一个列表中,像这样:
  2. >>> joeMarks = [55, 63, 77, 81]
  3. >>> tomMarks = [65, 61, 67, 72]
  4. >>> bethMarks = [97, 95, 92, 88]
  5. #或者对应每个课程使用一个列表,如下:
  6. >>> mathMarks = [55, 65, 97]
  7. >>> scienceMarks = [63, 61, 95]
  8. >>> readingMarks = [77, 67, 92]
  9. >>> spellingMarks = [81, 72, 88]
  10. #为成绩建立一个数据结构
  11. >>> classMarks = [joeMarks, tomMarks, bethMarks]
  12. >>> print(classMarks)
  13. [[55, 63, 77, 81], [65, 61, 67, 72], [97, 95, 92, 88]] #list of list
  14. >>> print(classMarks[0])
  15. [55, 63, 77, 81]
  16. >>> print(classMarks[0][2])
  17. 77

元组(tuple)

简单的说,就是不可改变的数组,用小括号表示:(a, b, c),没有增删改操作。因为 tuple 不可变,所以代码更安全。如果可能,能用 tuple 代替 list 就尽量用 tuple

来看一个“可变的”tuple:

  1. >>> t = ('a', 'b', ['A', 'B'])
  2. >>> t[2][0] = 'X'
  3. >>> t[2][1] = 'Y'
  4. >>> t
  5. ('a', 'b', ['X', 'Y'])

tuple 所谓的“不变”是说,tuple 的每个元素,指向永远不变。即指向 ‘a’,就不能改成指向 ‘b’,指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的!理解了“指向不变”后,要创建一个内容也不变的 tuple 怎么做?那就必须保证 tuple 的每一个元素本身也不能变。

只有1个元素的 tuple 定义时必须加一个逗号 ,,来消除歧义:

  1. >>> t = (1,)
  2. >>> t
  3. (1,)

解压

  1. t = (1, 10.31, ('OK', 'python'))
  2. (a, b, (c, d)) = t
  3. print(a, b, c, d)
  4. # 1 10.31 OK python

如果只想要元组其中几个元素,用通配符「*」,英文叫 wildcard,在计算机语言中代表一个或多个元素。

  1. t = 1, 2, 3, 4, 5
  2. a, b, *rest, c = t
  3. print(a, b, c)
  4. # 1 2 5
  5. print(rest)
  6. # [3, 4]
  7. #---------------------------------
  8. a, b, *_ = t
  9. print(a, b)
  10. # 1 2

Revison

  • 列表是什么。
  • 如何向列表中增加元素。
  • 如何从列表删除元素。
  • 何确定列表是否包含某个值。
  • 如何对列表排序。
  • 如何建立列表的副本。
  • 元组。
  • 双重列表。

测试题

  1. 向列表增加元素有哪些方法?
  2. 从列表删除元素有哪些方法?
  3. 要得到一个列表的有序副本,但又不能改变原来的列表,有哪两种方法?
  4. 怎样得出某个值是否在列表中?
  5. 如何确定某个值在列表中的位置?
  6. 什么是元组?
  7. 如何建立双重列表?
  8. 如何从一个双重列表中得到一个值?

动手试一试

  • 写一个程序,让用户提供 5 个名字。程序要把这 5 个名字保存在一个列表中,最后打印出来。就像这样: ```shell Enter 5 names: Tony Paul Nick Michel Kevin

The names are Tony Paul Nick Michel Kevin

  1. - 修改第 1 题的程序,要求不仅显示原来的名字列表,还要显示出排序后的列表。
  2. - 修改第 1 题的程序,要求只显示用户键入的第 3 个名字,就像这样:
  3. ```shell
  4. 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

  1. <a name="rB8wg"></a>
  2. # 十一、字典
  3. Python 列表是一种将元素组织在一起的方式。在编程中,经常会以另一种方式组织元素,将某个值和另一个值关联起来。这种组织方式就像电话通讯录将姓名和电话号码关联起来,也像字典将单词和它们的含义关联起来。
  4. Python 字典(dictionary)是一种将两个东西关联在一起的方式。被关联在一起的两个东西分别称为键(key)和值(value)。字典中的每个项(item)或条目(entry)都有一个键和一个值,它们合起来被称为键值对(key-value pair)。一个字典就是一些键值对的集合。
  5. 一个简单的例子就是电话通讯录。假设你想保存朋友们的电话号码。你会使用他们的姓名去查找他们的号码。这个姓名就是“键”,即你会用它来查找信息,而电话号码就是“值”,即你要查找的信息。
  6. ```python
  7. >>> phoneNumbers = {}
  8. >>> phoneNumbers["John"] = "555-1234"
  9. >>> print(phoneNumbers)
  10. {'John': '555-1234'}
  11. >>> phoneNumbers = {"John": "555-1234"}
  12. >>> phoneNumbers["Mary"] = '555-6789'
  13. >>> phoneNumbers["Bob"] = '444-4321'
  14. >>> phoneNumbers["Jenny] = '867-5309'
  15. >>> print(phoneNumbers)
  16. {'Bob': '444-4321','John': '1555-1234','Mary': '555-67891', 'Jenny': '1867-53091'}
  17. >>> print(phoneNumbers["Mary"])
  18. '555-6789'
  19. >>> print(phoneNumbers.keys())
  20. ['Bob', 'John', 'Mary', 'Jenny']
  21. >>> print(phoneNumbers.values())
  22. ['444-4321', '555-1234', '555-6789', '867-5309']
  23. for key in sorted(phoneNumbers.keys()):
  24. print(key, phoneNumbers[key])
  25. Bob 444-4321
  26. Jenny 867-5309
  27. John 555-1234
  28. 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

  • 字典。

测试题

  1. 什么是字典?
  2. 如何向字典中增加项?
  3. 怎样使用键去查找一个条目?

动手试一试

  • 编写一个字典程序,让用户可以添加单词和定义,然后可以查找这些单词。确保当要查找的单词不存在时,用户能够知晓。运行的时候,它应该是像这样的: ```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}

setdict 的唯一区别仅在于没有存储对应的 value,但是 set 的原理和 dict 一样,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证 set 内部“不会有重复元素”。试试把 list 放入 set,看看是否会报错。

测试题

  1. 创建一个空集合,增加 {‘x’,‘y’,‘z’} 三个元素。
  2. 求两个集合 {6, 7, 8}{7, 8, 9} 中不重复的元素。
  3. {'A', 'B', 'C'} 中元素在 {'B', 'C', 'D'} 中出现的次数。