> For the complete documentation index, see [llms.txt](https://luoran.gitbook.io/luo-ran-de-bi-ji-ben/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://luoran.gitbook.io/luo-ran-de-bi-ji-ben/python-bian-cheng/01python-ji-chu/05.-lie-biao.md).

# 05.列表

接下来一起来学习下列表

什么是列表？

列表就是一个有序的数据集合，在里面可以随意的添加和删除其中的元素，元素可以为任意类型

## **创建列表**

```
data1 = ['1',1] # 通过[]将数据放在一起

data2 = ['1',2,[1,2,3],4] # 列表中元素也可以为一个序列

empty = []
```

## **通过下标取得列表中的单个值**

注意，列表中的元素的位置，是从0开始计数的

```
>>> a = [1,2,3,4]
>>> a
[1, 2, 3, 4]
>>> a[0]
1
>>> a[1]
2
>>> a[2]
3
>>> a[3]
4
```

注意，如果下标的大小超过了列表中的元素个数，会报错

```
>>> a[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
```

## **负数下标**

在python中，支持负数下标。

```
>>> a = [1,2,3,4]
>>> a
[1, 2, 3, 4]
>>> a[-1]
4
>>> a[-2]
3
>>> a[len(a)-1]
4
>>> a[len(a)-2]
3
```

负数下标中整数值-1指的是列表中的最后一个下标，-2指的是列表中倒数第二个下标，以此类推。另外a\[-i] 等价于a\[len(a)-1]

## **如何使用切片**

如果想从列表提取多个值，该怎么办?使用下标的话，太麻烦了，这时可以使用切片，切片可以从列表中取得多个值，得到的结果是一个新的列表

### **格式**

```
list[start,stop,step]
```

### **参数**

* start:表示切片开始的下标位置
* stop:表示切片结束处的下标位置，不包括stop这个位置
* step:步长

### **实例**

```
>>> a = [1,2,3,4,5,6,7,8,9]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[1:]
[2, 3, 4, 5, 6, 7, 8, 9]
>>> a[1:len(a)]
[2, 3, 4, 5, 6, 7, 8, 9]

>>> a[:5]
[1, 2, 3, 4, 5]
>>> a[0:5]
[1, 2, 3, 4, 5]

>>> a[0:5:2]
[1, 3, 5]

>>> a[::2]
[1, 3, 5, 7, 9]
>>> a[0:len(a):2]
[1, 3, 5, 7, 9]
```

## **用del语句从列表中删除值**

del语句将删除列表中下标处的值，列表中被删除值后面的所有值，都将向前移动一个下标

```
>>> a = [1,2,3,4,5,6,7,8,9]

>>> a[1:5]
[2, 3, 4, 5]
>>> del a[1:5]
>>> a
[1, 6, 7, 8, 9]

>>> a[0]
1
>>> del a[0]
>>> a
[6, 7, 8, 9]
```

## **向列表添加元素**

* list.append(x)
  * 将项添加到列表的末尾。相当于。a\[len(a):] = \[x]

```
>>> a = [1,2,3,4,'angle']
>>> a
[1, 2, 3, 4, 'angle']
>>> a.append(2)
>>> a
[1, 2, 3, 4, 'angle', 2]
>>> a.append("name")
>>> a
[1, 2, 3, 4, 'angle', 2, 'name']
>>> a[len(a):] = ["123"]
>>> a
[1, 2, 3, 4, 'angle', 2, 'name', '123']
```

* list.extend(iterable)
  * 通过附加iterable中的所有项来扩展列表。相当于 。a\[len(a):] = iterable

```
>>> a = [1,2,3]
>>> a
[1, 2, 3]
>>> b = [4,5,6]
>>> a.extend(b)  # 将一个列表的元素追加到另一列表的末尾中
>>> a
[1, 2, 3, 4, 5, 6]
```

* list.insert(i,x)
  * 在给定位置插入项目,第一个参数是要插入的元素的索引,第二个参数是即将要插入的元素

```
>>> a = [1,3,5,7]
>>> a
[1, 3, 5, 7]
>>> a.insert(1,2) # 插入到第一个位置，也就是原来的3位置，插入后，3以及3以后的元素，都往后退一位
>>> a
[1, 2, 3, 5, 7]
>>> a.insert(3,4)
>>> a
[1, 2, 3, 4, 5, 7]
```

## **删除列表中的元素**

* list.remove(x )
  * 从列表中删除值等于x的第一个项目。ValueError如果没有这样的项目，它会引发一个

```
>>> a = [1,2,3,4,5,6]
>>> a
[1, 2, 3, 4, 5, 6]
>>> a.remove(1)  # 删除指定值相同的元素
>>> a
[2, 3, 4, 5, 6]
>>> a.remove(5)
>>> a
[2, 3, 4, 6]
```

* list.pop(\[ i ] )
  * 删除列表中给定位置的项目，然后将其返回。如果未指定索引，则a.pop()删除并返回列表中的最后一项。（方法签名中i周围的方括号表示该参数是可选的，而不是您应该在该位置键入方括号。您将在Python Library Reference中经常看到这种表示法）

```
>>> a
[1, 2, 3, 4, 5, 6]
>>> a.pop() # 默认删除最好一个元素，相当于a.pop(len(a)-1)
6
>>> a.pop(4) # 删除指定位置在第4个的元素
5
>>> a.pop(1)
2
>>> a
[1, 3, 4]
>>> a.pop(0)
1
>>> a
[3, 4]
```

* list.clear()
  * 从列表中删除所有项目,相当于del a\[:]

```
>>> a = [1,2,3,4,5,6]
>>> a
[1, 2, 3, 4, 5, 6]
>>> a.clear()  # 清除列表中的元素，但不会删除列表对象
>>> a
[]


>>> a = [1,2,3,4,5,6]
>>> del a  # 删除列表对象
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
```

## **查找列表中的值**

* list.index(x \[，start \[，end ] ] )
  * 在值等于x的第一个项的列表中返回从零开始的索引。ValueError如果没有这样的项目，则提高a 。
  * 可选参数start和end被解释为切片表示法，并用于将搜索限制为列表的特定子序列。返回的索引是相对于完整序列的开头而不是start参数计算的。

```
>>> a = [3,5,6,4,1,9]
>>> a
[3, 5, 6, 4, 1, 9]
>>> a.index(5)
1
>>> a.index(1)
4
>>> a.index(1,4)
4
>>> a.index(1,5)  # 为什么报错，因为索引是从第5个位置开始索引的
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 1 is not in list
>>> a.index(1,2,5)
4
>>> a.index(3,2,5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 3 is not in list
```

## **更新列表的值**

可以对列表的数据项进行修改或更新

```
>>> a = [1,2,3,4]
>>> a[0] = 'angle'
>>> a
['angle', 2, 3, 4]
```

## **为列表进行排序**

* list.sort(key = None，reverse = False )
  * 对列表中的项目进行排序（参数可用于排序自定义，请参阅sorted()其说明）

```
>>> a = [9,6,3,4,7,]
>>> a
[9, 6, 3, 4, 7]

>>> a.sort()
>>> a
[3, 4, 6, 7, 9]

# 利用key进行倒序排序
>>> a = [9,6,3,4,7,]
>>> a.sort(key=lambda x:-x)
>>> a
[9, 7, 6, 4, 3]

# 反向排序
>>> a = [9,6,3,4,7,]
>>> a.sort(reverse=True)
>>> a
[9, 7, 6, 4, 3]
```

* list.reverse()
  * 反转列表中的元素

```
>>> a
[9, 7, 6, 4, 3]
>>> a = [9,6,3,4,7,]

>>> a.reverse() # 这是反转列表，注意没有进行排序
>>> a
[7, 4, 3, 6, 9]
```

## **复制列表**

* list.copy()
  * 返回列表的浅表副本。相当于a\[:]

浅复制仅仅复制了容器中元素的地址

```
>>> a = [1,2,[3,4]]
>>> b = a.copy()    # 浅拷贝：深拷贝父对象（一级目录），子对象（二级目录）不拷贝，还是引用
>>> c = a           # 浅拷贝: 引用对象
>>> b
[1, 2, [3, 4]]
>>> a
[1, 2, [3, 4]]
>>> a[2]
[3, 4]

# 注意
>>> a[2].append(2)
>>> b
[1, 2, [3, 4, 2]]
>>> a.append(1)

# b[2]有新元素添加了，其余没变动
>>> b
[1, 2, [3, 4, 2]]
>>> a
[1, 2, [3, 4, 2], 1]
>>> c
[1, 2, [3, 4, 2], 1]
```

有时候一个一个输出相同的列表，很麻烦，这时候可以这样输出

```
>>> a = [1,2,3,4]
>>> a * 3 #这样就可以快速输出三个相同的列表，并且自动连接在一起
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
```

## **列表之间的连接**

列表之间的连接通过‘+’连接在一起

```
>>> a = [1,2,3,4]
>>> b = [5,6,7]
>>> a+b
[1, 2, 3, 4, 5, 6, 7]
```

## **列表用于循环**

```
>>> for i in range(4):
...     print(i)
...
0
1
2
3
```

range(4)的返回值是类似于列表的值，python认为类似于\[0,1,2,3]

```
>>> for i in [0,1,2,3]:
...     print(i)
...
0
1
2
3
```

前面的for循环实际上是在循环执行它的子句，在每次迭代中，让变量依次设置列表中的值

常见的python技巧，是在for循环中使用range(len(someList))，迭代列表中的每一个下标

```
>>> word = ["a","b","c","d"]
>>> word
['a', 'b', 'c', 'd']
>>> for i in range(len(word)):
...     print(word[i])
...
a
b
c
d
```

## **使用列表作为堆栈(先进后出)**

list方法可以很容易地将列表用作堆栈，其中添加的最后一个元素是检索到的第一个元素（“last-in，first-out”）。要将项添加到堆栈顶部，请使用append()。要从堆栈顶部检索项目，请在pop()没有显式索引的情况下使用

```
>>> stack = [1,2,3,]
>>> stack
[1, 2, 3]
>>> stack.append(4)
>>> stack
[1, 2, 3, 4]
>>> stack.pop()
4
>>> stack
[1, 2, 3]
```

## **使用列表作为队列(先进先出)**

要实现队列，请使用collections.deque设计为具有快速追加和从两端弹出的队列

### **描述**

返回一个从左到右（使用append()）初始化的新deque对象，其中包含来自iterable的数据。如果未指定iterable，则新的deque为空。

Deques是堆栈和队列的概括（名称发音为“deck”，是“双端队列”的缩写）。Deques支持线程安全，内存有效的附加和从双端队列的弹出，在任一方向上具有大致相同的O（1）性能。

虽然list对象支持类似的操作，但它们针对快速固定长度操作进行了优化，并且导致O（n）内存移动成本 pop(0)和操作，这些操作改变了底层数据表示的大小和位置。insert(0, v)

如果未指定maxlenNone，则deques可能会增长到任意长度。否则，双端队列限制为指定的最大长度。一旦有界长度双端队列已满，当添加新项目时，从对方端丢弃相应数量的项目。有界长度deques提供类似于tailUnix中的过滤器的功能。它们还可用于跟踪仅涉及最近活动的事务和其他数据池。

### **语法**

```
collections.deque([ iterable [，maxlen ] ] )
```

### **支持方法**

* append（x ）
  * 将x添加到双端队列的右侧。
* appendleft（x ）
  * 将x添加到双端队列的左侧。
* clear()
  * 从双端队列中删除所有元素，使其长度为0。
* copy()
  * 创建deque的浅表副本。
* count（x ）
  * 计算deque元素的数量等于x。
* extend（可迭代的）
  * 通过附加可迭代参数中的元素来扩展双端队列的右侧。
* extendleft（可迭代的）
  * 通过附加来自iterable的元素来扩展双端队列的左侧。注意，左边的序列会导致反转迭代参数中元素的顺序。
* index（x \[，start \[，stop ] ] ）
  * 返回deque中的x位置（在索引开始时或 索引停止之前）。返回第一个匹配或ValueError如果未找到则引发 。
* insert（i，x ）
  * 将x插入位置i的双端队列中。
  * 如果插入会导致有界双端超过maxlen，IndexError则会引发a。
* pop()
  * 从双端队列的右侧移除并返回一个元素。如果没有元素，则提出一个IndexError。
* popleft()
  * 从双端队列的左侧移除并返回一个元素。如果没有元素，则提出一个IndexError。
* remove（值）
  * 删除第一次出现的值。如果没有找到，提出一个 ValueError。
* reverse()
  * 在原地反转deque的元素然后返回None。
* rotate（n = 1 ）
  * 向右旋转deque n步。如果n为负数，则向左旋转。
  * 当双端队列不为空时，向右d.appendleft(d.pop())旋转一步相当于，向左旋转一步相当于d.append(d.popleft())。
* maxlen\*（只读属性）\*
  * 一个双端队列的最大大小或None无边界。

```
>>> from collections import deque
>>> d = deque('ghi')                 # make a new deque with three items
>>> for elem in d:                   # iterate over the deque's elements
...     print(elem.upper())
G
H
I

>>> d.append('j')                    # add a new entry to the right side
>>> d.appendleft('f')                # add a new entry to the left side
>>> d                                # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # return and remove the rightmost item
'j'
>>> d.popleft()                      # return and remove the leftmost item
'f'
>>> list(d)                          # list the contents of the deque
['g', 'h', 'i']
>>> d[0]                             # peek at leftmost item
'g'
>>> d[-1]                            # peek at rightmost item
'i'

>>> list(reversed(d))                # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d                         # search the deque
True
>>> d.extend('jkl')                  # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # empty the deque
>>> d.pop()                          # cannot pop from an empty deque
Traceback (most recent call last):
    File "<pyshell#6>", line 1, in -toplevel-
        d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])
```

### **列表推导式**

列表推导式（又称列表解析式）提供了一种简明扼要的方法来创建列表

举个栗子

```
a = []
for i in range(1,10):
    a.append(i)
print(a)
```

运行结果：

```
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

是不是看起来代码太多了，这时可以使用列表推倒式

```
b = [i for i in range(1,10)]
print(b)
```

运行结果:

```
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

这样写起来是不是方便很多了
