# 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]
```

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://luoran.gitbook.io/luo-ran-de-bi-ji-ben/python-bian-cheng/01python-ji-chu/05.-lie-biao.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
