python 內(nèi)置類型(四)---list/tuple/range

4.6. Sequence Types — list, tuple, range

python擁有三種基本的序列類型:lists, tuplesrange。其他的序列類型包括二進制類型(binary data)和字符串類型(text strings)將會在其他章節(jié)內(nèi)進行描述.

4.6.1. Common Sequence Operations

下面的操作支持大部分的序列類型,包括可變類型和不可變類型。python里提供的collections.abc.Sequence ABC是為了更容易在自定義序列類型上正確實現(xiàn)這些操作。

這個表格列舉的操作是根據(jù)優(yōu)先級排序的。在列表里,st是相同的序列類型。n,i,j是整數(shù),x是滿足任何類型限制的任意對象。

innot in操作有相同的優(yōu)先級.
+*操作與相應的數(shù)字操作具有相同的優(yōu)先級。[3]。

Operation Result Notes
x in s True if an item of s is equal to x, else False (1)
x not in s False if an item of s is equal to x, else True (1)
s + t the concatenation of s and t (6)(7)
s * n or n * s equivalent to adding s to itself n times (2)(7)
s[i] ith item of s, origin 0 (3)
s[i:j] slice of s from i to j (3)(4)
s[i:j:k] slice of s from i to j with step k (3)(5)
len(s) length of s
min(s) smallest item of s
max(s) largest item of s
s.index(x[, i[, j]]) index of the first occurrence of x in s (at or after index i and before index j) (8)
s.count(x) total number of occurrences of x in s

相同的序列類型還支持比較。具體地說,tuplelist通過字典順序來比較對應的元素。這表示如果兩個序列相等,則必須每個對應的元素都要相同,而且兩個序列的類型和長度必須相同。(想?yún)㈤唽脑敿毿畔?,可以參?a target="_blank" rel="nofollow">Comparisons )

標記:

1.x not in s --> innot in不止用于一般的的包容測試,一些特殊的序列類型(比如str,bytesbytearray)也可以使用它們進行包容測試:

    >>> "gg" in "eggs"
    True

2.s * n or n * s --> n小于0時被視為0(產(chǎn)生跟s類型相同的空類型)。請注意,序列s里面的item并沒有被copy,他們被重復引用多次(n次). 這個問題常常困擾新的python程序員。
考慮以下情況:

    >>> lists = [[]] * 3
    >>> lists
    [[], [], []]
    >>> lists[0].append(3)
    >>> lists
    [[3], [3], [3]]

為什么會發(fā)生這種情況呢,因為[[]]是一個包含一個[]元素的數(shù)組,因此[[]] * 3都是對這個空數(shù)組的相同引用,修改任意一個元素都會修改這個單獨的列表。
用指針的說法表示就是:創(chuàng)建了一個包含三個指針的數(shù)組,這三個指針都指向同一個地址。你可以通過另一種方式創(chuàng)建空數(shù)組:

    >>>lists = [[] for i in range(3)]
    >>> lists[0].append(3)
    >>> lists[1].append(5)
    >>> lists[2].append(7)
    >>> lists
    [[3], [5], [7]]

FAQ條目中提供了進一步的說明如何創(chuàng)建多維列表?.

3.s[i],s[i:j],s[i:j:k] --> 如果i 和j是負數(shù),i和j就會使用:len(s) + i 或者 len(s) + j 代替,但是-0還是0

if i < 0:
    i = len(s) + i
if j < 0:
    j = len(s) + j
  1. s[i:j] --> 從ij的對s的切片被定義為具有索引k的序列,使得i <= k < j。如果i或者jlen(s)的長度大,使用len(s)代替。如果i被省略或者iNone,使用0。如果j被省略或者jNone,使用len(s)代替。如果i大于等于j,則切片為空。

  2. s[i:j:k] --> s的從ij,具有索引為x = i + n * k的切片,其中n: 0 <= n < (j - i) / k.換句話說,指數(shù)為:i, i + k, i + 2 * k, i + 3 * k ......, 當x達到j時停止檢索,但是x不包括j。
    k是正數(shù)時,如果ijlen(s)大,他們將變?yōu)?減少到)len(s)
    k是負數(shù)時,如果ijlen(s)大,他們將變?yōu)?減少到)len(s)-1。
    如果i或者j被省略或者為None,他們將會變成結束值,結束值的數(shù)值取決于k的符號。如下所示:

# k不能等于0
# 如果k=None,k = 1
if k == None:
    k = 1
if k < 0:
    i = len(s) - 1
    j = 0
if j > 0:
    i = 0
    j = len(s) - 1

6.s + t --> 拼接不可變序列總是產(chǎn)生一個新序列。這意味著通過重復連接建立一個序列將在總序列長度中具有二次運行成本。要獲得線性運行時成本,您必須切換到以下其中一個選項:
* 如果拼接的是str類型,你可以生成一個序列,并且可以在末尾使用str.join()或寫入一個io.StringIO實例,并在完成時檢索其值
*如果拼接的是bytes類型,你可以相似的使用bytes.join()或者io.BytesIO,或者你可以使用bytearray代替,bytearray是可變的并且具有有效的分配機制
*如果拼接的是tuple類型,使用list代替
*如果拼接的是其他類型,請查看相關的類文檔
7.s + t --> 某些序列類型(如range)僅支持遵循特定模式的項目序列,因此不支持序列拼接或重復。

  1. s.index(x[, i[, j]]) --> 當在s中沒有找到xindex raises ValueError。不是所有的類型都支持傳遞附加的參數(shù)ij。這兩個參數(shù)允許有效的搜索序列的子部分。傳遞額外的參數(shù)大致相當于使用s [i:j] .index(x),只是不復制任何數(shù)據(jù),并且返回的索引是相對于序列的開始而不是切片的開始。

4.6.2. 不可變序列(Immutable Sequence Types)

唯一不可變的序列類型通常實現(xiàn)的操作不是通過可變序列類型實現(xiàn)的,這是對內(nèi)置的hash()的支持。
這種支持允許將不可變序列(如tuple實例)用作dictkey,并存儲在setfrozenset實例中。
嘗試hash包含不可hash的不可變序列將導致TypeError。

4.6.3. 可變序列(Mutable Sequence Types)

下表中的操作是在可變序列類型上定義的。python里提供的collections.abc.MutableSequence ABC是為了更容易在自定義序列類型上正確實現(xiàn)這些操作。
在表中s是一個可變序列類型的實例,t是任何可迭代的對象,x是一個任意的對象,滿足s施加的任何類型和數(shù)值限制(例如bytearray 只接受滿足值限制'0 <= x <= 255'的整數(shù))。

Operation Result Notes
s[i] = x item i of s is replaced by x
s[i:j] = t slice of s from i to j is replaced by the contents of the iterable t
del s[i:j] same as s[i:j] = []
s[i:j:k] = t the elements of s[i:j:k] are replaced by those of t (1)
del s[i:j:k] removes the elements of s[i:j:k] from the list
s.append(x) appends x to the end of the sequence (same ass[len(s):len(s)] = [x])
s.clear() removes all items from s (same as del s[:]) (5)
s.copy() creates a shallow copy of s (same as s[:]) (5)
s.extend(t) or s += t extends s with the contents of t (for the most part the same as s[len(s):len(s)] = t)
s *= n updates s with its contents repeated n times (6)
s.insert(i, x) inserts x into s at the index given by i (same as s[i:i]= [x])
s.pop([i]) retrieves the item at i and also removes it from s (2)
s.remove(x) remove the first item from s where s[i] == x (3)
s.reverse() reverses the items of s in place (4)

標記:

  1. 序列t的長度必須和切片的長度一樣.
  2. 參數(shù) i 默認是-1, 所以默認返回并刪除最后一個元素。
  3. s中沒有發(fā)現(xiàn)x時,remove raises ValueError.
  4. reverse()方法在倒置大序列時可以節(jié)省空間。為了提醒用戶它是以副作用的方式運行的,它不會返回相反的順序。
  5. 為了與不支持切片操作的可變?nèi)萜鞯慕涌冢ㄈ?code>dict和set)保持一致,使用了clear()copy()
    New in version 3.3: clear() and copy() methods.
  6. 值n是一個整數(shù),或者一個實現(xiàn)了__index__()的對象。n為零和負值時表示清除序列。序列中的item不是被復制;它們被多次引用,如Common Sequence Operations下的s * n所述。

4.6.4. Lists

數(shù)組是可變序列,經(jīng)常用于存儲同類項目的集合(精確的相似度因應用程序而異)。

class list([iterable])

Lists may be constructed in several ways:
列表可以以幾種方式構建:

  • 用一對方括號表示一個空數(shù)組:[]
  • 使用方括號,用逗號分隔item: [a], [a, b, c]
  • for循環(huán)一個list(Using a list comprehension): [x for x in iterable]
  • 使用類型構造函數(shù): list() or list(iterable)

構造函數(shù)list(iterable)構建一個列表,其items和iterable的item相同,并且item的順序也相同。iterable可能是一個序列,支持迭代的容器,也可以是迭代器對象。如果iterable也是一個list,將會copy一個新的list并且返回,相當于iterable[:]。如果沒有參數(shù)傳入,創(chuàng)建一個空序列。舉個例子:

>>>list("abc")
['a', 'b', 'c']
>>>list((1, 2, 3))
[1, 2, 3]
>>>list()
[]

許多其他操作也可以創(chuàng)建lists,包括內(nèi)建函數(shù)sorted().
list支持所有通用common方法和可變mutable方法(即以上兩個表格里的所有方法)。并且還支持以下的方法:

sort(*, key=None, reverse=False)

這個方法對列表進行排序,通過<(大小)比較對list里的item進行比較。異常不會被抑制 - 如果任何比較操作失敗,整個排序操作將失?。ú⑶伊斜砜赡軙A粼诓糠中薷臓顟B(tài))。

>>>l1 = [3, 2, 6, 3, 'xl', 9, 0] # 注意當前l(fā)1的排列順序
>>>l1.sort() # 對l1進行排序sort,報錯
Traceback (most recent call last):
  File "xx.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
TypeError: '<' not supported between instances of 'str' and 'int'
>>>l1 # 重新查看l1的數(shù)據(jù),發(fā)現(xiàn)數(shù)據(jù)的排列順序已經(jīng)改變
[2, 3, 3, 6, 'xl', 9, 0]

sort()accepts two arguments that can only be passed by keyword (keyword-only arguments):
sort()接受兩個只能通過關鍵字傳遞的參數(shù)key,reverse
key指定一個用于從每個列表元素提取比較鍵的參數(shù)的函數(shù)(例如key = str.lower)。對應于列表中每個項目的鍵被計算一次,然后用于整個排序過程。 “None”的默認值意味著列表項直接排序而不需要計算單獨的鍵值。

>>>l2 = ['5', '9', 9, 8, 7, '3', 1]
>>>l2.sort() # 類型不同,無法比較,報錯
Traceback (most recent call last):
  File "xx.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'str'
>>>l2.sort(key=int) #使用int()作用于每一個元素,然后進行比較
>>>l2
[1, '3', '5', 7, 8, '9', 9]

functools.cmp_to_key()可用于將2.x風格的cmp方法轉化為key方法

reverse是一個布爾值。如果設置為True,則列表元素按照相反的順序進行排序(逆序)。

這種方法在排序大序列時可以有效節(jié)省內(nèi)存空間。為了提醒用戶,它運行的副作用,此方法不返回排好序的序列(使用[sorted())

sort()方法保證穩(wěn)定。如果確保不會更改比較相等的元素的相對順序,則排序是穩(wěn)定的 - 這對于多次排序很有幫助。

CPython實現(xiàn)細節(jié):在列表正在排序時,試圖進行變異甚至檢查列表的效果時,列表是undefined。CPython實現(xiàn)使得列表在持續(xù)時間內(nèi)顯示為空,并且如果列表在排序過程中發(fā)生了變化,它可以檢測到ValueError

4.6.5. Tuples

元組是不可變的序列,通常用于存儲異構數(shù)據(jù)的集合(例如enumerate()生成的2元組)。 元組也用于需要存儲不變序列的同類數(shù)據(jù)的情況(例如允許存儲在setdict實例中)。

class tuple([*iterable*])

元組可以通過以下方式創(chuàng)建:

  • 使用一對小括號來創(chuàng)建一個空tuple: ()
  • 使用一個逗號結尾的單個tuple: a, or (a,)
  • 用逗號分隔項目: a, b, c or (a, b, c)
  • 使用內(nèi)置函數(shù)tuple(): tuple() or tuple(iterable)

構造函數(shù)tuple(iterable)構建一個元組,其元素與iterable的元素相同且順序相同。iterable可以是序列,支持迭代的容器,也可以是迭代器對象。如果iterable已經(jīng)是一個元組,返回數(shù)據(jù)不變。例如,tuple('abc')返回('a','b','c')tuple([1,2,3])返回(1,2,3) 。如果沒有參數(shù),構造函數(shù)將創(chuàng)建一個新的空元組``()`。

請注意,元組實際上是由逗號組成的,而不是括號。除了在空元組的情況下,或當他們需要避免語法歧義時,括號是可選的。例如,f(a,b,c)是一個帶有三個參數(shù)的函數(shù)調(diào)用,而f((a,b,c))是一個以3-tuple作為唯一參數(shù)的函數(shù)調(diào)用。

tuple支持所有的通用序列操作

對于數(shù)據(jù)的異質(zhì)集合,其中通過名稱訪問比由索引訪問更清晰,collections.namedtuple()可能是一個比簡單的元組對象更合適的選擇。

4.6.6. Ranges

range類型表示numbers的不可變序列,并通常用于for循環(huán)中。

class range(stop)
class range(start, stop[, step])

range構造函數(shù)的參數(shù)必須是整數(shù)(內(nèi)置[int]或任何實現(xiàn)__index__特殊方法的對象)。
如果省略step參數(shù),則默認為1。
如果省略start參數(shù),則默認為0。
如果step為零,則引發(fā)'ValueError`

對于step > 0,range的實例對象r的內(nèi)容由以下公式確定:r[i] = start + step * i where (i >= 0 and r[i] < stop).請注意,這里r[i] < stop.

對于step < 0,range的實例對象r的內(nèi)容由以下公式確定:r[i] = start + step * i where (i >= 0 and r[i] > stop).請注意,這里r[i] > stop.

# 偽代碼
if step > 0:
    int i = 0
    while r[i] < stop:
        r[i] = start + step * i
        i += 1
if step < 0:
    int i = 0
    while r[i] > stop:
        r[i] = start + step * i
        i += 1

如果r [0]不符合值約束,range對象將為空。range確實支持負指數(shù),但這些被解釋為從正指數(shù)確定的序列末尾開始的索引。(可以參考切片的理解)

range的元素中包含有大于sys.maxsize的元素是被允許的,但是一些方法可能會引發(fā)OverflowError,比如說len()

Range examples:

>>>list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))
[]
>>> list(range(1, 0))
[]

范圍實現(xiàn)所有通用序列操作,除了連接和重復(由于范圍對象只能表示序列遵循嚴格的模式,重復和連接通常會違反該模式)。

start
start參數(shù)的值(如果參數(shù)未提供,則為0
stop
stop參數(shù)的值
step
step參數(shù)的值(如果參數(shù)未提供,則為1

range類型比listtuple好的一個地方是:一個range對象將總是采取相同(?。┑膬?nèi)存量,無論它代表的范圍的大小(因為它只存儲“start”,“stop”和“step”的值,在使用時再根據(jù)需要計算單個項目和子范圍)。

Range對象支持collections.abc.Sequence ABC方法,提供諸如包含測試,元素索引查找,切片和負指數(shù)支持等功能:

>>>r = range(0, 20, 2)
>>> r
range(0, 20, 2)
>>> 11 in r
False
>>> 10 in r
True
>>> r.index(10)
5
>>> r[5]
10
>>> r[:5]
range(0, 10, 2)
>>> r[-1]
18

測試range對象的==和!=時,將它們作為序列進行比較。也就是說,如果兩個range序列對象表示的值相同,則它們被認為是相等的。 (請注意,比較相等的兩個范圍對象可能會有不同的start,stopstep.例如range(0)== range(2,1,3)range(0,3,2)== range(0,4) ,2)。

>>>range(0)
range(0, 0)
>>>range(2, 1, 3)
range(2, 1, 3)
>>>list(range(0))
[]
>>>list(range(2, 1, 3))
[]

在版本3.2中更改:實現(xiàn)序列ABC。支持切片和負指數(shù)。在恒定時間測試[int]成員的對象,而不是迭代所有項目。

在版本3.3中更改:定義'=='和'!='以根據(jù)它們定義的值序列比較范圍對象(而不是根據(jù)對象標識進行比較)。

3.3版新增功能:start,stopstep屬性。

也可以看看

  • linspace recipe顯示如何實現(xiàn)適合浮點應用程序的惰性版本的范圍

通用序列(common)操作表格摘抄

x in s True if an item of s is equal to x, else False (1)
x not in s False if an item of s is equal to x, else True (1)
s + t the concatenation of s and t (6)(7)
s * n or n * s equivalent to adding s to itself n times (2)(7)
s[i] ith item of s, origin 0 (3)
s[i:j] slice of s from i to j (3)(4)
s[i:j:k] slice of s from i to j with step k (3)(5)
len(s) length of s
min(s) smallest item of s
max(s) largest item of s
s.index(x[, i[, j]]) index of the first occurrence of x in s (at or after index i and before index j) (8)
s.count(x) total number of occurrences of x in s

可變序列(mutable)操作表格摘抄

s[i] = x item i of s is replaced by x
s[i:j] = t slice of s from i to j is replaced by the contents of the iterable t
del s[i:j] same as s[i:j] = []
s[i:j:k] = t the elements of s[i:j:k] are replaced by those of t (1)
del s[i:j:k] removes the elements of s[i:j:k] from the list
s.append(x) appends x to the end of the sequence (same as s[len(s):len(s)] = [x])
s.clear() removes all items from s (same as del s[:]) (5)
s.copy() creates a shallow copy of s (same as s[:]) (5)
s.extend(t) or s += t extends s with the contents of t (for the most part the same as s[len(s):len(s)] = t)
s *= n updates s with its contents repeated n times (6)
s.insert(i, x) inserts x into s at the index given by i (same as s[i:i] = [x])
s.pop([i]) retrieves the item at i and also removes it from s (2)
s.remove(x) remove the first item from s where s[i] == x (3)
s.reverse() reverses the items of s in place (4)
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,038評論 0 23
  • 太棒了,我正在成長!太棒了,反正死不了,再來一次! 不舒服是因為跨出習慣領域 當碰到困難、遇到挫折的時候,通常也是...
    周明達老師閱讀 1,241評論 1 20
  • 手機:mi4 軟件版本:3.2.0.1 接觸渠道:優(yōu)酷自制節(jié)目《女神有藥》 體驗時長:3周 -----------...
    今夏Summer閱讀 4,329評論 8 20
  • 不要平白無故羨慕別人的優(yōu)秀,任何你看到的優(yōu)秀都有別人背后的努力。不要與別人比,你開始時,別人已經(jīng)跑了很長時間。不妄...
    劉樂丹的閱讀 175評論 0 0
  • 黑熊/文 01 不知道什么時候“大眾創(chuàng)業(yè),萬眾創(chuàng)新”的口號,開始悄無聲息的進入了我們的生活。無論是咖啡館、水吧、快...
    黑熊愛折騰閱讀 1,085評論 0 2

友情鏈接更多精彩內(nèi)容