## 資料類型詳解-清單
> 清單就是一組有序的資料組合,清單中的資料可以被修改
## 清單的定義
+ 可以使用 中括号進行定義 []
+ 也可以使用 list函數 定義
+ 在定義清單中的元素時,需要在每個元素之間使用逗号,進行分隔。[1,2,3,4]
+ 清單中的元素可以是任意類型的,通常用于存放同類項目的集合
## 清單的基本操作
+ 清單定義-[],list()
+ 清單相加-拼接
+ 清單相乘-重複
+ 清單的下标- 擷取,更新
+ 清單元素的添加-append()
+ 清單元素的删除
+ del 清單[下标]
+ pop()函數 删除元素
## 清單中切片
> 文法==> 清單[開始索引:結束索引:步進值]
1。 清單[開始索引:] ==> 從開始索引到清單的最後
2。 清單[:結束值] ==> 從開始到指定的結束索引之前
3。 清單[開始索引:結束索引] ==> 從開始索引到指定結束索引之前
4。 清單[開始索引:結束索引:步進值] ==> 從指定索引開始到指定索引前結束,按照指定步進進行取值切片
5。 清單[:] 或 清單[::] ==> 所有清單元素的切片
6。 清單[::-1] ==> 倒着擷取清單的元素
示例:
```python
varlist = ['劉德華','張學友','張國榮','黎明','郭富城','小沈陽','劉能','宋小寶','趙四']
# 從開始索引到清單的最後
res = varlist[2:] # ['張國榮','黎明','郭富城','小沈陽','劉能','宋小寶','趙四']
# 從開始到指定的結束索引之前
res = varlist[:2] # ['劉德華','張學友']
# 從開始索引到指定結束索引之前
res = varlist[2:6] # ['張國榮', '黎明', '郭富城', '小沈陽']
# 從指定索引開始到指定索引前結束,按照指定步進進行取值切片
res = varlist[2:6:2] # ['張國榮', '郭富城']
# 所有清單元素的切片
res = varlist[:]
res = varlist[::]
# 倒着輸出清單的元素
res = varlist[::-1]
# 使用切片方法 對清單資料進行更新和删除
print(varlist)
# 從指定下标開始,到指定下标前結束,并替換為對應的資料(容器類型資料,會拆分成每個元素進行指派)
# varlist[2:6] = ['a','b','c',1,2,3]
# varlist[2:6:2] = ['a','b'] # 需要與要更新的元素個數對應
# 切片删除
# del varlist[2:6]
del varlist[2:6:2]
```
## 清單相關函數
```python
varlist = ['劉德華','張學友','張國榮','張學友','黎明','郭富城','小沈陽','劉能','宋小寶','趙四']
# len() 檢測目前清單的長度,清單中元素的個數
res = len(varlist)
# count() 檢測目前清單中指定元素出現的次數
res = varlist.count('張學友')
# append() 向清單的尾部追加新的元素,傳回值為 None
varlist.append('川哥')
# insert() 可以向清單中指定的索引位置添加新的元素,
varlist.insert(20,'aa')
# pop() 可以對指定索引位置上的元素做 出棧 操作,傳回出棧的元素
res = varlist.pop() # 預設會把清單中的最後一個元素 出棧
res = varlist.pop(2) # 會在清單中把指定索引的元素進行 出棧
varlist = [1,2,3,4,11,22,33,44,1,2,3,4]
# remove() 可以指定清單中的元素 進行 删除,隻删除第一個。如果沒有找到,則報錯
res = varlist.remove(1)
# index() 可以查找指定元素在清單中第一次出現的索引位置
# res = varlist.index(1)
# res = varlist.index(1,5,20) # 可以在指定索引範圍内查找元素的索引位置
# extend() 接收一個容器類型的資料,把容器中的元素追加到原清單中
# varlist.extend('123')
# s.clear() # 清空清單内容
# varlist.clear()
# reverse() 清單翻轉
varlist.reverse()
# sort() 對清單進行排序
res = varlist.sort() # 預設對元素進行從小到大的排序
res = varlist.sort(reverse=True) # 對元素進行從大到小的排序
res = varlist.sort(key=abs) # 可以傳遞一個函數,按照函數的處理結果進行排序
```
## 深拷貝與淺拷貝
### 淺拷貝
> 淺拷貝隻能拷貝清單中的一維元素,**如果清單中存在二維元素或容器,則引用而不是拷貝**
>
> 使用cpoy函數或者copy子產品中的copy函數拷貝的都是淺拷貝
```python
# 淺拷貝 隻能拷貝目前清單,不能拷貝清單中的多元清單元素
varlist = [1,2,3]
# 簡單的拷貝 就可以把清單複制一份
newlist = varlist.copy()
# 對新拷貝的清單進行操作,也是獨立的
del newlist[1]
# print(varlist,id(varlist))
# print(newlist,id(newlist))
'''
[1, 2, 3] 4332224992
[1, 3] 4332227552
'''
# 多元清單
varlist = [1,2,3,['a','b','c']]
# 使用copy函數 拷貝一個多元清單
newlist = varlist.copy()
'''
print(newlist,id(newlist))
print(varlist,id(varlist))
[1, 2, 3, ['a', 'b', 'c']] 4361085408
[1, 2, 3, ['a', 'b', 'c']] 4361898496
'''
# 如果是一個被拷貝的清單,對它的多元清單元素進行操作時,會導緻原清單中的多元清單也發生了變化
del newlist[3][1]
'''
通過id檢測,發現清單中的多元清單是同一個元素(對象)
print(newlist[3],id(newlist[3]))
print(varlist[3],id(varlist[3]))
['a', 'c'] 4325397360
['a', 'c'] 4325397360
'''
```
### 深拷貝
> 深拷貝就是不光拷貝了目前的清單,**同時把清單中的多元元素或容器也拷貝了一份,而不是引用**
>
> 使用copy子產品中的 deepcopy 函數可以完成深拷貝
```python
# 深拷貝 就是不光拷貝了目前的清單,同時把清單中的多元元素也拷貝了一份
import copy
varlist = [1,2,3,['a','b','c']]
# 使用 copy子產品中 深拷貝方法 deepcopy
newlist = copy.deepcopy(varlist)
del newlist[3][1]
print(varlist)
print(newlist)
'''
print(newlist[3],id(newlist[3]))
print(varlist[3],id(varlist[3]))
['a', 'c'] 4483351248
['a', 'b', 'c'] 4483003568
'''
```
## 清單推到式
>List-Comprehensions
>
>清單推導式提供了一個更簡單的建立清單的方法。
>
>常見的用法是把某種操作應用于序列或可疊代對象的每個元素上,然後使用其結果來建立清單,或者通過滿足某些特定條件元素來建立子序列。
>
>采用一種表達式的當時,對資料進行過濾或處理,并且把結果組成一個新的清單
### 一,基本的清單推到式使用方式
> 結果變量 = [變量或變量的處理結果 for 變量 in 容器類型資料]
示例:
```python
# 1 假設我們想建立一個平方清單
# 使用普通方法完成
varlist = []
for i in range(10):
varlist.append(i**2)
# print(varlist) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 使用 map函數和list完成
varlist = list(map(lambda x: x**2, range(10)))
# print(varlist) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 使用清單推到式完成 下面這個清單推到式和第一種方式是一樣的
varlist = [i**2 for i in range(10)]
# print(varlist) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 2。 '1234' ==> [2,4,6,8]
# 正常方法完成需求
varstr = '1234'
newlist = []
for i in varstr:
newlist.append(int(i)*2)
# print(newlist) # [2, 4, 6, 8]
# 使用清單推到式完成上面的需求
newlist = [int(i)*2 for i in varstr]
# print(newlist) # [2, 4, 6, 8]
# 使用清單推到式+位運算完成
newlist = [int(i) << 1 for i in varstr]
# print(newlist) # [2, 4, 6, 8]
```
### 二,帶有判斷條件的清單推到式
> 結果變量 = [變量或變量的處理結果 for i in 容器類型資料 條件表達式]
示例:
```python
# 0-9 求所有的偶數,==> [0, 2, 4, 6, 8]
# 正常方法完成
newlist = []
for i in range(10):
if i % 2 == 0:
newlist.append(i)
# print(newlist) # [0, 2, 4, 6, 8]
# 清單推到式完成
newlist = [i for i in range(10) if i % 2 == 0]
# print(newlist) # [0, 2, 4, 6, 8]
```
### 三,對于嵌套循環的清單推到式
```python
'''
# 下面這個 3x4的矩陣,它由3個長度為4的清單組成,交換其行和列
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
==>
[
[1, 5, 9],
[2, 6, 10],
[3, 7, 11],
[4, 8, 12]
]
'''
arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
# 正常方法完成
# newlist = []
# for i in range(4):
# res = []
# for row in arr:
# res.append(row[i])
# newlist.append(res)
# print(newlist)
# 使用清單推到式完成
newlist = [[row[i] for row in arr] for i in range(4)]
print(newlist)
```