1. 列表和元組為何要總放在一起
列表和元組在基礎篇已經好好的研究了基礎用法,你應該保留乙個基本印象就是列表和元組,就是乙個可以放置任意資料型別的有序集合,或者當成乙個容器也可以。
它們兩個最直接的區別就是,列表長度大小不固定,可變,元組長度大小固定,不可變。
在很多地方,會把這種區別叫做動態與靜態。
這裡最常見的乙個錯誤就是給元組賦值或者修改值了,錯誤提示如下,出現了要知道原因是啥?
typeerror: 'tuple' object does not support item assignment
如何去給元組增加資料呢,我想你應該也比較清楚了,就是新建立乙個元組,把新的資料和舊的資料一拼接,搞定。
# 夢想橡皮擦 專用的反爬蟲注釋
my_old_tuple = (1, 2, "a", "b")
my_new_tuple = ("c", "d")
my_tuple = my_old_tuple+my_new_tuple
print(my_tuple)
對於基礎部分,還有要注意的就是,元組如果只有乙個元素,一定要這麼寫 (1,) ,逗號不要遺漏,遺漏了括號裡面是啥資料型別,最後得到的就是那個資料型別的資料了。
1.1 列表和元組的切片
列表和元組都是有序的,有序就能切片,而切片記住是顧頭不顧尾的操作,例如下述**。
my_tuple = my_old_tuple+my_new_tuple
print(my_tuple[1:3])
在剛學習切片的時候,乙個比較常見的錯誤如下,該錯誤產生的原因是, 中括號裡面的 : 寫成其他符號了。
typeerror: tuple indices must be integers or slices, not tuple
1.2 負數索引與二者相互轉換
列表與切片二者都支援負數索引取值,但是需要知道負數索引是從 -1 開始的,為啥?自己琢磨。
小聲嘀咕:還不是因為 0 只有乙個
二者也可以互相轉換,轉換應用的是內建的函式 list 和 tuple,順著函式學習下去,列表與元組都有一些可以應用的內建函式,這部分在滾雪球第一遍學習的時候,咱已經都搞定了,很簡單的知識點。
1.3 列表與元組的儲存方式
執行下述**檢視執行結果,列表與元組元素數目保持一致。
my_list = ["a", "b", "c"]
print(my_list.__sizeof__())
my_tuple = ("a", "b", "c")
print(my_tuple.__sizeof__())
輸出的結果存在差異,相同元素資料的列表與元組,系統給列表分配的空間要大一些
第乙個知識點是 __sizeof__(): 表示的列印系統分配空間的大小。
接下來我們對其進行一下基本的測試,從列表檢測系統分配是如何進行空間分配的。
my_list =
print("初始化大小",my_list.__sizeof__())
print("追加1個元素之後的大小",my_list.__sizeof__())
print("追加2個元素之後的大小",my_list.__sizeof__())
print("追加3個元素之後的大小",my_list.__sizeof__())
print("追加4個元素之後的大小",my_list.__sizeof__())
print("追加5個元素之後的大小",my_list.__sizeof__())
執行結果為:
初始化大小 40
追加1個元素之後的大小 72
追加2個元素之後的大小 72
追加3個元素之後的大小 72
追加4個元素之後的大小 72
追加5個元素之後的大小 104
增加乙個元素之後,大小變成了 72,然後連續增加 4 個元素,系統分配的大小都沒有變化,地 5 個元素,又增加了 32 位元組空間,這樣已經可以得到結論了:
列表會一次性的增加 4 個元素的空間,當空間使用完畢之後,才會繼續增加。
上述**的原理:
列表從本質上看,是乙個動態的陣列,列表中並不是儲存的真實資料,而是每個元素在記憶體中的位址(引用),因為列表儲存是元素的引用這個特性,所以引用占用的記憶體空間是相同的,也就是 8 個位元組,並且這樣可以儲存不同型別的資料。
在 64 位的作業系統中,位址占用 8 個位元組,如果你的電腦是 32 位,那位址占用的是 4 個位元組,注意下即可。
1.4 列表和元組的應用場景
簡單來說,元組用在固定元素內容的資料上,列表用在可變的資料上,在希望記憶的簡單一些,可以直接記成如果只需要 2、3 個元素,就使用 tuple,元素在多就使用 namedtuple,它是乙個函式。
使用 namedtuple 需要先進行匯入。
from collections import namedtuple
help(namedtuple)
函式原型如下:
namedtuple(typename, field_names, *, rename=false, defaults=none, module=none)
# returns a new subclass of tuple with named fields.
先寫一段測試**:
from collections import namedtuple
point = namedtuple('point', ['x', 'y'])
p = point(10, 20)
print(p.x)
print(p.y)大連**醫院
前面兩個引數需要簡單學習一下。
typename:字串型別的引數,這個引數理解起來比較繞,貼一下官方的解釋,namedtuple() 會根據這個 typename, 建立乙個子類類名返回出去,例如上文的測試**中的 point,建立好的類名稱就是 point ,第二個引數就是以後的類屬性了。
field_names:用於為建立的元組的每個元素命名,可以傳入列表或者元組,例如 ['a', 'b'] 、(a,b),也可以傳入'a b' 或 'a,b' 這種被逗號或空格分割的單字串。
上文中如果你希望看到類被構建的過程,可以增加引數 verbose,但是這個引數在官網也有相關的說明,有的版本是不支援的,在 python 3.7 之後就沒有該屬性了。
changed in version 3.6: the verbose and rename parameters became keyword-only arguments.
changed in version 3.6: added the module parameter.
changed in version 3.7: removed the verbose parameter and the _source attribute.
changed in version 3.7: added the defaults parameter and the _field_defaults attribute.
初始化空列表是使用 list() 還是使用
該內容可以使用下述**進行一下效率的測試。
import timeit
a = timeit.timeit('a=list()', number=10000000 )
b = timeit.timeit('a=', number=10000000 )
print(a)
print(b)
執行結果:
1.6634819
0.5888171999999998
結論是 速度更快,因為 list() 是函式呼叫,效率肯定要低一些。
有了上述函式,你也可以測試一下相同的元素在列表與元組初始化的時候,哪個效率更好。
import timeit
a = timeit.timeit('a=("a","b","c")', number=10000)
b = timeit.timeit('b=["a","b","c"]', number=10000)
print(a)
print(b)
執行結果如下:
# 初始化元組
0.0005571000000000048
# 初始化列表
0.002022099999999999
Python學習之路 列表
任何程式語言都免不了對資料的處理,而變數存在的意義就是方便資料的訪問,但是在特定情況下我們需要對很多的資料處理,如果都一一定義變數那未免太繁瑣了。python提供了一種高階資料型別可以同時存放多個資料值,就是列表。列表名 元素1,元素2,元素3.元素n 列表名符合一般變數的命令規範,裡面存放資料,每...
python之路 列表,元組
列表 list 基礎資料型別之一,可以索引,切片,步長,切片 步長可以增刪改查,可迭代,可巢狀字典,元組,列表 一 索引,切片,步長 list01 1,2,3,eric west 1.索引 fz list01 0 print fz result 1 反向查詢 print list01.index 1...
Python高階之路 一
一 python基礎語法知識 第一天 1 變數 定義 為了儲存 程式運算過程中的一些中間 結果,為了方便日後呼叫,資料修改 命名規則 1 由字母 數字 下劃線組成 2 不能以數字開頭,不能含有特殊的字元和空格 3 不能以保留字命名 4 不建議以中文命名 5 定義的變數名應該有意義 見名知意 6 駝峰...