1. 程式人生 > >(二)python語法之列表

(二)python語法之列表

列表是python的內建可變序列,對python列表的操作也是基於值得自動記憶體管理機制,即如果對一列表得行內元素進行刪除或者擴充套件,那麼python會對列表物件進行擴張或者收縮,從而保證元素在記憶體種沒有間隔。

列表的建立

列表得建立有三種方式

  • 通過賦值直接建立 a=[]
  • 通過list方法進行資料型別轉換a=list((1,2,3,5))
  • 通過range([start,]stop[,step])方法進行建立

列表元素的增加

列表元素得增加分為兩個方向得增加,第一個方向是變成新的記憶體地址得對列表;第二個方法是在原來列表得記憶體地址上進行增加,後者得方式是真正的增加。不改變列表的記憶體地址,也符合列表的可變序列的特質。現在來說明如何實現這兩種方式的列表增加; 增加後變成新的記憶體地址的列表

  • ”,使用"”運算子,能夠實現原列表的重複;
  • “+”,使用 "+"運算子[1,2]+[3,4]

真正意義上的增加,使用列表的屬性

  • insert屬性,list.insert(index,data),將data資料加入到list中的index下標的地方;
  • extend屬性,list1.extend(list2),將list2中的全部元素加到list1列表中;
  • append屬性,list.append(data);將data資料加入list列表中的末尾;

列表元素的刪除

列表元素的刪除,分為兩種方式的刪除;關鍵字刪除和列表屬性刪除。 關鍵字刪除 就是使用del

del list[1]

列表屬性的刪除

  • pop(),刪除列表中的最後一個值,並返回這個值。
  • remove()方法,用於移除列表中某個值的第一個匹配項。

基於值的記憶體自動管理與列表

python基於值的記憶體自動記憶體管理對於列表元素的增加和刪除有一些影響。

對於增加

由於是基於值得記憶體自動管理,所以在列表中間增加一個值,會導致這個下標後面得值,全部向後移動,會導致大大的增加記憶體的消耗和時間的消耗。所以對於列表元素的增加,最好是增加到列表的末尾,這樣子可以大幅度提高程式的執行時間

import time
start1=time.time()
a=list(range(1,100000000))
a.insert(2,10)
start2=
time.time() a.append(10) start3=time.time() print(start2-start1) print(start3-start2) # 執行結果 # 第一個輸出是2.2665457725524902,第二個輸出是0.0

可以看出效率的差別了。所以對列表的增加刪減工作最好是從列表末尾開始

對於刪除

其實對於增加還是可以的,只是時間和記憶體的增加。但是刪減的話,反而會報錯。來看下面的兩段程式碼,就指出了這個問題

a=[1,1,2,3,4,5]
for i in a:
    if i==1:
        a.remove(i)
print(a)

最後的結果確是[1,2,3,4,5].還有下面第二段程式碼

x=[1,2,1,2,1,1,1]
for x in range(len(x)):
    if x[i]==1:
		    del x[i]

這段程式碼執行後會報錯。“list index out of range” 上面的兩個問題都是由python的基於值得記憶體自動管理系統造成得,即python刪除元素後會先自動進行記憶體管理,保證列表中的元素中間沒有空隙,才會接著執行python程式碼。導致了。所以刪除元素必須要求從後向前刪除。

列表元素的訪問與計數

列表的訪問方式

  • 使用列表的方法,index(),list.index(object),加入索引,返回這個object元素首次出現的位置的下標,如果列表中無該元素則會報錯。
  • 使用切片方式,切片方式也是對列表的淺層賦值即list[start,stop,step]。
  • 列表元素的計數,使用count(object),就能夠知道object元素在該列表中出現了幾次。

成員資格判斷

即是用"in"與“not in"的運算子。

切片

列表的切片不會因為下標越界而丟擲異常,而是簡單的在列表的尾部截斷或者放回一個空列表(如果切片出來的區域沒有列表元素的話) 切片的使用方式也很簡單,只要在切片中增加三個數,即可切得到一塊區域。[start,stop,step].切片是淺層複製,即再切片獲取到的是一個新的列表,比如看下面這段程式碼

>>> x=[1,2,3]
>>> id(x)  # 第一處
2961803576200
>>> x=x
>>> id(x)  # 第二處
2961803576200
>>> x=x[::]
>>> id(x)  # 第三處 
2961803593800

可以看出上面的第一處和第二處相同(列表的深層複製)第二處和第三處相同(列表的淺層複製)

列表排序

列表排序這裡來說明排序的兩種方式,第一種是列表的方法sort()排序,第二種是python的內建函式sorted排序

列表的方法排序

list.sort()使用方式很簡單,但是使用方式也很單調,只有一個關鍵字list.sort(reverse=True)來進行倒置排序,比如從大到小。

python的內建函式sorted

sorted(iterable, *, key=None, reverse=False)現在來說明一下這三個

  • iterable可迭代物件
  • reverse是否倒置
  • key是關鍵字,這個是一個函式,這個函式的特別之處就是放入的是可迭代物件中的元素,返回的是元素中的一個部分,最好的就是使用匿名函式lamble。下面來舉一個例子,
# 按照item的第二個元素從大到小排序
item1=(1,2,3)
item2=(1,1,3)
item3=(1,4,3)
item4=(1,5,3)
li=[item1,item2,item3,item4]
ans=sorted(li,key=lambda x :x[1] , reverse=True)
print(ans)

運算的結果:[(1, 5, 3), (1, 4, 3), (1, 2, 3), (1, 1, 3)]

用於序列操作的常用內建函式

zip()內建函式,使用方式,如:zip(list1,list2,list3),將多個列表或者元組對應位置的元素組合成元組(這個就要求了每個列表都應該具有相同的長度),並返回包含這些元組的列表,下面舉一個例子。

>>> list1=[1,2,3,4,5]
>>> list2=[5,4,3,2,1]
>>> list3=[0,9,8,7,6]
>>> list4=zip(list1,list2,list3)
>>> list4
<zip object at 0x00000225D45D63C8>
>>> list(list4)
[(1, 5, 0), (2, 4, 9), (3, 3, 8), (4, 2, 7), (5, 1, 6)]

enumerate()內建函式,這個函式迭代序列,返回一個元組,這個二元元組,第二個元素是是這個迭代出來的資料,第一個元素,就是這個元素所在的下標。下面舉一個例子。

>>> list=['a','b','c','d','e','f']
>>> for item in enumerate(list):
...     print(item)
...
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')

map(),這個函式需要兩個引數,即map(function,Iterable),這個函式的作用是什麼,就是將可迭代資料進行一一的map,function需要注意的有兩點,第一點必須有一個引數,第二點,必須返回一個數據。下面來舉例一個。

>>> def f(x):
...     return x * x
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>>
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

filter()內建函式,filter()函式用於過濾序列。接收的函式與map一樣也是一個函式和一個序列。不過這個函式有一點特別之處就是返回的資料要是布林型別,即把傳入的函式依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素。下面有一個例子

def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 結果: [1, 5, 9, 15]

列表生成器

list=[x for x in iterable], 現在來講一下列表生成器的比較有趣的用法。

>>> a=["1-2","2-3","3-4","4-5"]
>>> b=[x.replace('-','') for x in a]
>>> b
['12', '23', '34', '45']

這個有點類似python的內建函式map.

>>> a=[1,21,3,1,2,321,31,3,1211,3,31,3,1,1]
>>> b=[x for x in a if x >19]
>>> b
[21, 321, 31, 1211, 31]

這個就是將if加到了列表生成器中

>>> x=[1,2,3,4]
>>> y=[2,3,4,5]
>>> [(a,b) for a in x for b in y]
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (3, 4), (3, 5), (4, 2), (4, 3), (4, 4), (4, 5)]

經過了上面的三個例子,我們可以來歸納一下列表生成器。 [元素 for for for 。。。多重迴圈 條件語句 過濾]

列表的常用方法

列表的常用方法 說明
list.append(x) 在列表末尾新增x
list.extend(L) 在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)
list.insert(index, obj) 將物件插入列表
list.remove(obj) 移除列表中某個值的第一個匹配項
list.pop([index=-1]) obj – 可選引數,要移除列表元素的索引值,不能超過列表總長度,預設為 index=-1,刪除最後一個列表值。
list.index(obj) 從列表中找出某個值第一個匹配項的索引位置
list.count(obj) 統計某個元素在列表中出現的次數
list.reverse() 反向列表中元素
list.copy() 淺層複製