python編程基礎——基本數據類型之列表


Python內置的數據類型列表(list)是一個可變的對象序列。在python中我們一般不區分列表和數組,(其他語言中則需要區分,因爲數組長度是固定的,不支持插入和刪除。下文中若無特殊說明數組和列表等價)我們使用列表作爲數組除了實現數組的基本功能外,python列表還允許插入元素和刪除元素。你也可以把列表理解爲是一種高級的數組。
list中的元素是任意類型的, 可以是int、 str, 還可以是list, 甚至是dict等。

基本操作

a=[3,6,7,9,10,4]
b=[2,5,1]

基本操作
量級 操作 結果 描述
常量 len(a) 6 列表a的長度
常量 a[4] 10 列表a的第4項(索引訪問操作)
常量 a[4]=9 9 列表a的第4項替換成9(索引賦值操作)
常量 a.pop()1 4 相當於出棧
線性 a+b [3, 6, 7, 9, 10, 4, 2, 5, 1] 列表a和b拼接
線性 a[2:5] [7,9,10] 切片操作
線性 a[2:5]=b2 [3, 6, 2, 5, 1, 4] 將a的切片部分替換爲b
線性 min(a) 3 最小項
線性 max(a) 10 最大項
線性 sum(a) 39 求和
線性 4 in a True 若包含則爲True,不包含則爲False(包含操作)
常量 b+=[6] [2,5,1,6] 將6附加到b的尾部(就地拼接操作)
線性 del b[1]3 [2,1] 從列表中刪除b[1](索引刪除操作)
線性 b.insert(2,9) [2, 5, 9, 1] (指定位置插入) 將9插入到a[2]的前面,單次僅運行插入一個元素
線性 b.reverse() [1, 5, 2] 列表a中的各項反序
線性 b.sort [1,2,5] 將列表a中各項升序排序
線性 a.index(7) 2 項7第一次出線在列表a中的索引號

可變數組

可變數組是一個存儲一系列數據項的不定長度的數據結構,可以通過索引下標訪問各項數據元素。

在實現方面,當用戶創建一個可變數組時,python先創建一個固定長度n的數組。在內存中以n爲大小劃分連續內存單元,用於存儲各項數據的內存地址(即引用)。那麼我們怎麼知道一個數組用於引用所使用的空間佔用了連續分配空間的多少呢?這裏我們使用屬於大小(size)表示所使用的個數容量(capacity)表示n的大小。例如python爲a=[4,3,5]劃分了10個連續的內存單元,那麼size=3,capacity=10。

當size==capacity時,表示當前所劃分的連續內存單元被佔滿,這時則創建一個長度是原來兩倍容量大小的連續內存單元,並將舊數據複製過來。反之若size<=capacity/2時,則創建一個capacity=capacity/2大小的連續內存空間,並將舊數據複製過來。這樣就能最大限度保證內存單元得到充分利用。(當然本文提到的擴容壓縮實際使用的倍數可能不同,但原理是一樣的。)


下圖顯示的是可變數組在隨着引用的增加而進行2倍擴容:
example

索引和切片

先來回顧一下字符串的索引和切片

>>> str="asdqwe"
>>> str[2]
'd'
>>> str[:3]
'asd'
>>> str[:-3]
'asd'
>>> str[1:3]
'sd'

在Python中,因爲列表和字符串的內存存儲上很相似,所以在索引和切片上也很相似。
索引數字從左邊開始編號,第一個是0,然後依次增加1。此外還有一種編號方式是從右邊開始,右邊第一個編號爲-1,然後依次是-2,-3,…,依次類推

>>> a=['a',123,'asdqwe']
>>> a[1]
123
>>> a[:2]
['a', 123]
>>> a[1:]
[123, 'asdqwe']
>>> a[:-1]
['a', 123]

序列的切片, 一定要左邊的數字小於右邊的數字,否則返回的是一個空。

反轉

[::-1]反轉

反轉在編程中常常會用到。值得一提的是反轉後原來的值並沒有改變。

>>> a=[1,2,3,4,5,6]
>>> a[::-1]
[6, 5, 4, 3, 2, 1]
>>> b="123456"
>>> b[::-1]
'654321'

reversed()反轉

# 它返回一個可以迭代的對象
>>> reversed(a)
<list_reverseiterator object at 0x000002983B1AFE10>

# a的值不改變
>>> list(reversed(a))
[6, 5, 4, 3, 2, 1]
>>> list(reversed(b))
['6', '5', '4', '3', '2', '1']

# a的值改變
>>> a.reverse()
>>> a
[3, 5, 4, 3, 2, 1]


添加和刪除

append()和a[len(a):]=[x]追加

append()和a[len(a):]=[x]追加是一個意思,都是在最後添加一個元素

>>> a
[3, 5, 4, 3, 2, 1]
>>> a.append(9)
>>> a
[3, 5, 4, 3, 2, 1, 9]
>>> a[len(a):]=[7]
>>> a
[3, 5, 4, 3, 2, 1, 9, 7]

extend()和a[len(a):]=L追加

extend()和a[len(a):]=L追加是一個意思,都是在最後添加一個列表

>>> a=[1,2,3]
>>> b=[1,1,1]
>>> a.extend(b)
>>> a
[1, 2, 3, 1, 1, 1]

extend()和append()的區別

對於extend()是在列表的最後接上另一個列表,對於append()則是在列表最後添加一個新的元素。可以從下面看出兩者的不同區別。

>>> a=[1,2,3]
>>> b=[1,1,1]
>>> c="asd"
>>> a.append(b)
>>> a
[1, 2, 3, [1, 1, 1]]
>>> a.extend(b)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1]
>>> a.extend(c)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1, 'a', 's', 'd']
>>> a.append(c)
>>> a
[1, 2, 3, [1, 1, 1], 1, 1, 1, 'a', 's', 'd', 'asd']
>>> a.extend(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

extend的對象是一個list,如果是str,則Python會先把它按照
字符爲單位轉化爲list再追加到已知list。append的對象數據類型無要求。


pop和remove刪除

  • list.remove(x)
    Remove the first item from the list whose value is x.It is an error if there
    is no such item.
  • list.pop([i])
    Remove the item at the given position in the list,and return it.If no
    index is specified,a.pop()removes and returns the last item in the list.(The
    square brackets around the i in the method signature denote that the
    parameter is optional,not that you should type square brackets at that
    position.You will see this notation frequently in the Python Library
    Reference.)

可以看出pop和remove都是刪除列表中的元素,不同的是pop是通過索引來刪除

>>> a=[1,2,3,4,5]
>>> a.remove(2)
>>> a
[1, 3, 4, 5]
>>> a.remove(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

>>> a=[1,2,3,4,5]
>>> a.pop(2)
3
>>> a
[1, 2, 4, 5]
>>> a.pop()
5
>>> a
[1, 2, 4]

插入

python中提供了insert(i,x)函數,這個函數有裏那個參數,即在a[i]前插入x。

>>> a=[1,2,3]
>>> a.insert(1,7)
>>> a
[1, 7, 2, 3]

如果insert的插入位置超出了列表a的索引位置時,該如何插入呢?如果遇到那個i已經超過了最大索引值,會自動將所要
插入的元素放到列表的尾部,即追加。
如果插入的位置i爲負時,則在倒是第| i |個位置前插入值。

>>> a.insert(9,5)
>>> a
[1, 7, 2, 3, 5]
>>> a.insert(-2,5)
>>> a
[1, 7, 2, 5, 3, 5]


排序

sort是對列表進行排序。默認是從小到大排序,當reverse=True時,爲從大到小排序。
我們先來看一下開發文檔是怎麼說的:

>>> help(list.sort)
Help on method_descriptor:

sort(self, /, *, key=None, reverse=False)
    Stable sort *IN PLACE*.

其中 “ / ” 是使用位置 , “ * “ 表示使用關鍵字

  • 使用位置-僅當名稱不重要或沒有意義,並且只有少數參數將始終以相同的順序傳遞。
  • 使用關鍵字-僅當名稱有意義時,而函數定義通過對名稱的顯式定義更容易理解。
>>> a=[9,3,4,6]
>>> a.sort()
>>> a
[3, 4, 6, 9]
>>> a.sort(reverse=True)
>>> a
[9, 6, 4, 3]

關於sorted可以參見史上最全關於sorted函數的10條總結

列表和字符串的相互轉化

str.split()

這個內置函數是將str以指定的分割字符切分字符串爲列表,我們先看一下函數說明:

split(sep=None, maxsplit=-1) method of builtins.str instance
    Return a list of the words in the string, using sep as the delimiter string.

    sep
      The delimiter according which to split the string.
      None (the default value) means split according to any whitespace,
      and discard empty strings from the result.
    maxsplit
      Maximum number of splits to do.
      -1 (the default value) means no limit.

簡言之,在str.split()函數中,有兩個參數,第一個就是分割符,用於拆分字符串的分隔符。默認表示根據任何空格進行拆分, 並從結果中丟棄空字符串。第二個是分割塊數。默認是最大分隔塊數。

>>> str="helllo,world"
>>> str.split(",")
['helllo', 'world']
>>> str.split("l",1)
['he', 'llo,world']
>>> str.split("l",4)
['he', '', '', 'o,wor', 'd']
#使用默認值進行分割
>>> s = "I am, writing\npython\tbook on line"
>>> s.split()
['I', 'am,', 'writing', 'python', 'book', 'on', 'line']

" ".join()

如果說split()是將string轉化爲list,那麼join就是將string轉化爲string。join可以說是split的逆運算。

>>> str
['using', 'sep', 'as', 'the', 'delimiter.']
>>> " ".join(str)
'using sep as the delimiter.'
>>> "-".join(str)
'using-sep-as-the-delimiter.'

多維列表

在列表中,元素可以是任何類型,因此列表也可以由列表組成,這樣就構成了二維列表,三維列表…

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


列表解析

列表解析是一個非常有意思的功能,列表解析爲創建列表提供了一種簡潔的方法。常見的應用是創建新列表,其中每個元素是應用於另一個序列的每個成員或可迭代的某些操作的結果,或者創建滿足特定條件的那些元素的子序列。

>>> squares = [x**2 for x in range(1,10)]
>>> squares
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> s = [str(x) for x in squares]
>>> s
['1', '4', '9', '16', '25', '36', '49', '64', '81']

  1. 默認值是棧頂,且一次僅允許出棧一個元素,如果想pop出a[i],則只需a.pop(i),如a.pop(4),結果爲[3, 6, 7, 9, 4] ↩︎

  2. a切片部分和b一定要滿足相等的關係嗎?當然不是,例如:a[2:4]=b,替換後a=[3, 6, 2, 5, 1, 10, 4],那a[i:i]=b能運行嗎?令人驚奇的是可以 例如,a[2:2]在a[1]和a[2]間插入了b,結果爲[3, 6, 2, 5, 1, 7, 9, 10, 4] ↩︎

  3. del可以用於刪除指定位置的某一段索引例如del a[2:4]=[3,6,10,4]。值得注意的是del b[:] 僅僅是刪除了b中的索引並沒有刪掉b這個列表,此時的輸出結果是 [ ],而del b則是刪除整個列表,此時如果再輸出b則會報錯 name ‘b’ is not defined↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章