Python 筆記(一)

Written by Python高效編程

應(yīng)用

  • 大文本查找單詞并修改
  • 重命名圖片或者文件
  • 小型數(shù)據(jù)庫(kù)
  • 特定目的的 GUI
  • 簡(jiǎn)單的小游戲

流程:寫程序/編譯/測(cè)試/重編譯 過程漫長(zhǎng)

shell 適合移動(dòng)代赁、修改文件宪哩,但不適合用戶界面或者游戲

c/c++/Java 耗時(shí)過長(zhǎng),即使是初稿

Python 使用起來更簡(jiǎn)單折联,跨平臺(tái)颓屑,幫助你更快速地完成工作斤寂。

Python 雖然簡(jiǎn)單易用,但也是通用編程語(yǔ)言揪惦。相較于其他腳本語(yǔ)言遍搞,Python 提供了多得多的適合于大型項(xiàng)目的結(jié)構(gòu)與支持。作為高級(jí)語(yǔ)言器腋,Python 相較于 C 語(yǔ)言提供更多的錯(cuò)誤檢查溪猿,并且有高度封裝的數(shù)據(jù)類型钩杰,比如靈活的矩陣和字典。Python 相較于 Awk 甚至是 Perl诊县,事何更加復(fù)雜的領(lǐng)域讲弄,盡管許多方面使用起來差不多方便。

Python 允許你把程序分割成可以重復(fù)使用的模塊依痊,你可以將模塊用在其他 Python 項(xiàng)目中避除。你還可以使用 Python 內(nèi)置的標(biāo)準(zhǔn)模塊,或者作為開始學(xué)習(xí) Python 的范例抗悍。一些模塊提供:文件讀取寫入驹饺,系統(tǒng)調(diào)用,sockets編程,甚至是用戶界面接口工具 TK。

Python 是解釋型語(yǔ)言邑滨,編譯和linking是不必要的匿值,在程序開發(fā)的時(shí)候,可以節(jié)省可觀的時(shí)間读虏。你可以通過交互式終端執(zhí)行 Python 程序,因此很容易就可以實(shí)驗(yàn)語(yǔ)言的特性,寫一些一次性的程序指蚁,或者在自下而上開發(fā)時(shí)測(cè)試函數(shù)。同時(shí)自晰,Python 是容易使用的桌面計(jì)算器凝化。

可擴(kuò)展性強(qiáng)

非正式介紹

  • 數(shù)值類型:浮點(diǎn)型,整型酬荞,復(fù)數(shù)(j or J) , 字符串

  • 各種操作符 :// , / , * 搓劫,** ,%混巧,+/-

  • 先賦值枪向,再使用

  • 整型 + 浮點(diǎn)數(shù) = 浮點(diǎn)數(shù)

  • 交互模式 _ = ans

字符串

  • ‘ . . . ’ or “ . . . ” 單引號(hào)或者雙引號(hào)
  • \ 可以忽略‘ “ it’s ok!” 或者 ‘ It'ok ’ 或者 ‘ yes “好的呢” ’
  • 交互模式,輸出字符以引號(hào)括起咧党,特殊字符仍保留(\n)
  • print 沒有引號(hào)秘蛔,沒有特殊字符
  • 不想 \被解釋為特殊字符,使用原生字符串(raw strings)在第一個(gè)引號(hào)前
  • 字符串可以跨越多行傍衡。一種方式是使用三個(gè)引號(hào)‘''...'’'或者·“""...""”
  • 也可以使用 \ 注釋
  • +連*倍
  • ‘Py’ ‘thon'
  • 當(dāng)你想斷開長(zhǎng)字符深员,這個(gè)方法特別又要
  • 只有個(gè)部分均為字符串文字(literals),而不是變量或者表達(dá)式
  • 連接變量與文字 請(qǐng)使用 +
  • 支持 index 0 起始
  • 沒有單獨(dú)的字符類型(char)蛙埂,一個(gè)字符就是長(zhǎng)度為1的字符串
  • 支持負(fù)數(shù)下標(biāo)倦畅,從右開始 -1
  • 切片操作
  • 索引獲取單個(gè)字符,切片獲取子字符串
  • s = s[:i] + s[i:]
  • 省略的第一個(gè)下標(biāo)默認(rèn)為 0
  • 省略的第二個(gè)下標(biāo)默認(rèn)為字符串長(zhǎng)度
  • 標(biāo)上序號(hào)記憶
P y t h o n
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
  • 左開右閉
  • 索引不能超過大小
  • 而切片卻可以
  • strings 常量不可修改(immutable:numbers,strings,tuples:(1,2))
  • word[0] = ‘J’
  • len(s) 返回字符串大小

列表

  • 復(fù)合數(shù)據(jù)類型
  • 寫作方括號(hào)與逗號(hào)的組合
  • 支持索引與切片
  • [:] 淺拷貝
  • 支持+*
  • 可修改 cube(立方)
  • append 后插
  • 賦值 可以改變列表大小箱残,甚至清空
  • letters[2:5] = [‘d’,‘e’] or []
  • 支持 len
  • 嵌入子列表

更加復(fù)雜的任務(wù)

# 斐波那契數(shù)列
a, b = 0,1
while b < 10:
    print(b)
    a, b = b, a + b
  • 多賦值 a,b = b,a simultaneously
  • 表達(dá)式順序
  • 左右 = 首先執(zhí)行
  • while 一直執(zhí)行滔迈,只要判斷條件成立
  • 類似 C止吁,任何非零值都是成立的,0 是 False。
  • 字符串燎悍、列表敬惦、任何不為空的序列。
  • 各種比較符 與 C 類似
  • 循環(huán)的主體是要縮進(jìn)的谈山,縮進(jìn)是 Python 組成語(yǔ)句的方式俄删。
  • Tab 四個(gè)字符縮進(jìn)
  • print 打印多個(gè)參數(shù),浮點(diǎn)數(shù)奏路,字符串
  • 字符串無引號(hào)畴椰,以逗號(hào)隔開的元素,打印時(shí)會(huì)用空格隔開
  • end 參數(shù)用于分隔每個(gè) print 打印的內(nèi)容 ‘,’ 避免換行
  • 優(yōu)先級(jí)

if 語(yǔ)句

  • 類似其他語(yǔ)言的條件語(yǔ)句
  • if x < 0 :
  • elif x == 0:
  • else:
  • elif 可以有 0 個(gè)鸽粉,或是更多斜脂,else是可選的
  • elif 是 else if 的縮寫,避免了不必要的1縮進(jìn)
  • 可替代 switch case

for 語(yǔ)句

  • 有些不同 相對(duì)于 C 和 Pascal
  • C 中既定義了迭代條件和停止條件
  • for 迭代 任何序列的元素(列表或者字符串)触机,按照出現(xiàn)順序
  • words
  • 如果迭代時(shí)你想修改序列值帚戳,推薦先做個(gè)拷貝
  • 迭代并不會(huì)拷貝數(shù)值
  • 切片隱式拷貝[:] 特別方便
  • 不拷貝,會(huì)無限迭代儡首,創(chuàng)建無窮列表
words = ['cat', 'window', 'defenestrate']
for w in words[:]:  
    if len(w) > 6: 
        words.insert(0, w)

range() 函數(shù)

  • 迭代數(shù)字序列
  • range(10) 序列大小為 10
  • 合理的索引值為 10
  • 不包含結(jié)束點(diǎn)片任,默認(rèn)初始值為 0
  • 可以設(shè)置間隔或者步長(zhǎng)(甚至可以是負(fù)數(shù))
  • range(-10, -100, -30)
  • 為了可以迭代序列的索引,可以同時(shí)使用 range 和 len
  • enumerate()
  • strange: print(range(10))
  • range 似乎是個(gè)列表蔬胯,實(shí)際上不是

它是一個(gè)當(dāng)你迭代它時(shí)对供,返回迭代序列連續(xù)元素的對(duì)象。但是它并不生成列表氛濒,因此節(jié)省了空間产场。這樣的對(duì)象是可迭代的,這種結(jié)構(gòu)的特點(diǎn)是:你可以連續(xù)從中獲取元素泼橘,直到?jīng)]有為止涝动。for 語(yǔ)句是迭代器,函數(shù)list()也是迭代器炬灭,它可以從可迭代對(duì)象中創(chuàng)建列表

break continue else

  • break 跳出最內(nèi)層循環(huán)醋粟,只跳出一層循環(huán)
  • else 子句
  • 當(dāng) for 循環(huán)結(jié)束,執(zhí)行else 或者 while 判斷條件為 False
  • 與 for 一起使用 類似于與 try 一起使用
  • try : else 用于沒有異常發(fā)生重归,for : else 用于沒有 break 語(yǔ)句
for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            break
    else:
           # loop fell through without finding a factor
        print(n, 'is a prime number')
  • continue 也是從 C 中借用的語(yǔ)句米愿,繼續(xù)開始下一次的迭代

pass

  • pass 語(yǔ)句什么都不做,當(dāng)語(yǔ)法上需要但是不需要執(zhí)行的時(shí)候
  • While True : pass
  • class MyEmptyClass : pass
  • 函數(shù)占位鼻吮,條件主體育苟,允許你考慮更抽象的水平

定義函數(shù)

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()
  • 創(chuàng)建斐波那契函數(shù)到任意邊界
  • def 關(guān)鍵字用于定義函數(shù) + 函數(shù)名 + (參數(shù))
  • 語(yǔ)句形成了函數(shù)的主體。必須被縮進(jìn)
  • 函數(shù)主體的第一條語(yǔ)句可以是字符串
  • 字符串是函數(shù)的說明文檔(docstring)
  • 養(yǎng)成說明的習(xí)慣
  • 函數(shù)的執(zhí)行引進(jìn)了新的符號(hào)表椎木,局部變量

更準(zhǔn)確地說违柏,在函數(shù)中分配的變量博烂,儲(chǔ)存在局部符號(hào)表格中(locak symbol table)

變量引用查找局部變量符號(hào)表格,然后是封閉函數(shù)的局部符號(hào)表格漱竖,接著是全局符號(hào)表格禽篱,最后是內(nèi)置函數(shù)名。因此馍惹,全局變量不能直接在函數(shù)中直接賦值給全局變量(除非使用 global 語(yǔ)句)躺率,盡管我們可以引用全局變量。

函數(shù)的實(shí)參万矾,在被調(diào)用函數(shù)的局部符號(hào)表格中悼吱。因此函數(shù)傳遞參數(shù)的引用,而不是參數(shù)的值良狈。數(shù)值不會(huì)被改變(常量)后添,列表會(huì)被改變。

當(dāng)函數(shù)調(diào)用另一個(gè)函數(shù)们颜,這次調(diào)用會(huì)創(chuàng)建新的局部符號(hào)表格吕朵。

函數(shù)定義在當(dāng)前符號(hào)表格中引進(jìn)了新的函數(shù)名。函數(shù)名的值的類型被解釋器當(dāng)成用戶定義函數(shù)窥突。這個(gè)值可以分配其他名字,我們可以通過其他名字調(diào)用這個(gè)函數(shù)硫嘶,這就是重命名機(jī)制的原理:

fib
f = fib
f(100)

函數(shù)沒有 return 語(yǔ)句也會(huì)返回值阻问,return None,None 被解釋器抑制了沦疾。如果它是唯一寫入的值称近,對(duì)于交互模式解釋器,使用print哮塞。

  • return 語(yǔ)句從函數(shù)中返回?cái)?shù)值刨秆,return 后面沒有表達(dá)式參數(shù)的話,會(huì)返回 None忆畅。
  • ulist.append 被稱為 list 對(duì)象 ulist 的方法衡未。這個(gè)方法是屬于一個(gè)對(duì)象的函數(shù),被命名為 obj.methodname家凯,其中 obj 是某些對(duì)象(也可能是表達(dá)式)缓醋。而 methodname 是由對(duì)象類型確定的方法名。不同的對(duì)象確定不同的方法绊诲。不同對(duì)象的方法可能會(huì)有相同的方法名送粱,卻不會(huì)引起歧義。你可以是由 class 定義你自己的對(duì)象類型掂之。append 正是 list 對(duì)象的方法抗俄,它在 list 的末尾增加一個(gè)新元素脆丁,這等同于 result = result + [a],但是更加高效动雹。

更多關(guān)于定義函數(shù)的知識(shí)

默認(rèn)參數(shù)值

  • 設(shè)定默認(rèn)值
  • def ask_ok(prompt, retries=4, reminder=‘a(chǎn)gain’)
  • 只給一個(gè)強(qiáng)制參數(shù)
  • 給出一個(gè)可選參數(shù)
  • 給出全部參數(shù)
  • in 用于判斷一個(gè)序列是否有某個(gè)值
  • 默認(rèn)值在函數(shù)定義前給出
i = 5

def f(arg=i):
    print(arg)

i = 6
f()
# 打印 5

警告:

初始值只被計(jì)算一次偎快。這使得當(dāng)初始值是可變對(duì)象(列表,字典洽胶,或者大多數(shù)類)晒夹,會(huì)有一些不同。舉個(gè)例子姊氓,下面的函數(shù)會(huì)累計(jì)傳遞給序列的參數(shù)丐怯。

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))
輸出:
[1]
[1, 2]
[1, 2, 3]

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

關(guān)鍵字(Keyword Arguments)

通過使用關(guān)鍵字參數(shù)(kwarg=value),我們可以調(diào)用函數(shù)翔横。

  • 關(guān)鍵字參數(shù) 必須在位置參數(shù)之后
  • 非關(guān)鍵字參數(shù)要在關(guān)鍵字參數(shù)之前
  • 正確:12, state = ‘jump’
  • 錯(cuò)誤:voltage = 12, ‘jump’
  • 每個(gè)參數(shù)不能重復(fù)接受值

*arguments **keywords

  • **name 接受字典 keyword = value return dict
  • *name 接受元組包含所有的位置參數(shù)读跷,超出正式參數(shù)列表
  • *name 必須在 **name 的前面
def f(*age,**name):
    print(age)
    print(name)
f(1,4,'sd',key = 'sd',time = '12')

任意參數(shù)列表

  • 最后,最不常用的的選項(xiàng)可以用任意數(shù)目參數(shù)禾唁,這些參數(shù)將會(huì)被包裹在元組中效览,零個(gè)或者多個(gè)參數(shù)都可以。
  • 可變參數(shù)(variadic)荡短,必須在正式參數(shù)的最后丐枉,因?yàn)樗鼈兘邮苁S嗨袀鬟f給函數(shù)的輸入?yún)?shù)
  • 任何在 *arg 后面的參數(shù),必須是“keyword-only”參數(shù)掘托,也就是說瘦锹,必須以關(guān)鍵字的形式而不是位置參數(shù)形式使用關(guān)鍵字
def concat(*args, sep="/"):
    print(sep.join(args))
    
concat("earth", "mars", "venus", sep=".")
concat("earth", "mars", "venus")

解包函數(shù)參數(shù)列表

相反的情況,就是參數(shù)已經(jīng)在列表或者元組中了闪盔,但是函數(shù)調(diào)用需要分離的位置參數(shù)弯院,這是我們就要將列表或者元組解包。舉個(gè)例子泪掀,內(nèi)置函數(shù) range 需要 start 和 stop 參數(shù)听绳。如果這些參數(shù)不能被分別得到,我們就要用到 * 操作符進(jìn)行解包來獲取列表或者元組中的參數(shù)异赫。相似的椅挣,我們可以使用 **dict 來獲取字典中元素。

a = {'name':'xkk', 'age':18, 'hobby': 'read'}
f(**a)

lambda 表達(dá)式

小型匿名(anonymous)函數(shù)祝辣,可以使用關(guān)鍵字 lambda贴妻。這個(gè)函數(shù)返回兩個(gè)關(guān)鍵字的和:lambda a, b: a+b。lambda 函數(shù)可以在需要函數(shù)對(duì)象的地方使用蝙斜。在語(yǔ)法上名惩,它被限制為單個(gè)表達(dá)式。從語(yǔ)義上講孕荠,它們正常定義函數(shù)的語(yǔ)法糖(syntactic sugar)娩鹉,類似于內(nèi)置函數(shù)定義攻谁,lambda 函數(shù)可以引用包含范圍內(nèi)的變量。

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

文檔說明

下面是一些關(guān)于說明文檔內(nèi)容與格式的慣例弯予。

第一行因該是對(duì)于對(duì)象目標(biāo)簡(jiǎn)短而準(zhǔn)確的介紹戚宦。簡(jiǎn)單地說,它不應(yīng)該明確說明對(duì)象的名字和類型锈嫩,因?yàn)檫@些可以通過其他方式介紹受楼,除非對(duì)象名碰巧是描述函數(shù)操作的動(dòng)詞。這一行應(yīng)該以大寫字母開頭呼寸,以句號(hào)結(jié)束艳汽。(end with a period)

如果說明文檔有多行,那么第二行應(yīng)該是空白行对雪,視覺上分割總結(jié)與其余部分河狐。接下來的內(nèi)容,應(yīng)該是一段或者更多段落瑟捣,描述調(diào)用慣例和副作用(side effects)馋艺。

Python 解釋器并不會(huì)從多行字符文字中去除縮進(jìn)。所以如果需要的話迈套,處理文本的工具必須去除縮進(jìn)捐祠。我們通過以下慣例實(shí)現(xiàn)。第一個(gè)行之后的第一個(gè)非空行確定整個(gè)文本的縮進(jìn)數(shù)目交汤。(我們不能使用第一行雏赦,因?yàn)樗ǔEc字符串的開頭引號(hào)相鄰,所以它的縮進(jìn)在文本中并不明顯)芙扎。所有行的字符串的開頭被去除與之相同的空白。缺少縮進(jìn)的行不應(yīng)該出現(xiàn)填大,但是所有行領(lǐng)先的空白應(yīng)該被去除戒洼。應(yīng)在擴(kuò)展標(biāo)簽后測(cè)試空格的有效性。

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

功能注釋(Function Annotations)

功能注釋關(guān)于用戶定義函數(shù)使用的類型的可選元數(shù)據(jù)信息允华。

注釋作為字典存儲(chǔ)在函數(shù)的__annotations__屬性中圈浇,對(duì)函數(shù)的其他任何部分沒有任何影響。功能注釋被參數(shù)名后面的冒號(hào)所定義靴寂,后面可以用表達(dá)式表示參數(shù)值磷蜀。返回注釋有 –> 定義,后面是表達(dá)式百炬,在參數(shù)列表與表示 def 語(yǔ)句結(jié)束的冒號(hào)之間褐隆。下面的例子有一個(gè)位置參數(shù),一個(gè)關(guān)鍵字參數(shù)剖踊,并且返回值被注釋了庶弃。

def f(ham: str, eggs: str = 'eggs') -> str:
    print("Annotations:", f.__annotations__)
    print("Arguments:", ham, eggs)
    return ham + ' and ' + eggs
f('spam')

間奏曲(intermezzo):代碼風(fēng)格

  • 既然你準(zhǔn)備寫更長(zhǎng)衫贬、更復(fù)雜的 Python 代碼,我們很有必要來討論代碼的風(fēng)格歇攻。
  • 大多數(shù)語(yǔ)言可以用多種風(fēng)格表示固惯,更準(zhǔn)確地說格式化。
  • 一些的可讀性較強(qiáng)缴守,使你的代碼讓別人輕易地讀出來總是一個(gè)好主意葬毫,采用一種比較好地代碼風(fēng)格非常有幫助。
  • 對(duì)于 Python 來說屡穗,PEP 8 已經(jīng)成為大多數(shù)項(xiàng)目接受的指導(dǎo)風(fēng)格贴捡,它提出一種可讀性強(qiáng),賞心悅目的代碼風(fēng)格鸡捐。每一個(gè) Python 開發(fā)者都應(yīng)該在某個(gè)時(shí)刻讀一下指南栈暇,下面是為你歸納出來的最重要的幾點(diǎn):
  • 使用 4 個(gè)空格的縮進(jìn),而不是 tabs

四個(gè)空格在大小縮進(jìn)得到了平衡(縮進(jìn)短允許更大的嵌套深度箍镜,縮進(jìn)長(zhǎng)更易于閱讀)源祈,Tabs 會(huì)導(dǎo)致誤解,最好被省略色迂。

  • 每一行不超過 79 個(gè)字符

這有助于用戶使用小型顯示器香缺,并且實(shí)現(xiàn)了在較大顯示器并排顯示代碼文件

  • 使用空行去分隔函數(shù)與類和函數(shù)中較大的代碼塊
  • 盡可能在每一行寫下他們的注釋
  • 使用說明文檔、
  • 在操作符和之后之后使用空格歇僧,但是不直接包圍結(jié)構(gòu):a = f(1, 2) + g(3, 4)
  • 命名你的類與函數(shù)要一致图张,慣例是使用駝峰(CameCase)命名法命名類,小寫字母和下標(biāo)命名函數(shù)與方法诈悍』雎郑總是使用 self 作為方法的第一個(gè)參數(shù)。
  • 不要使用花哨的編碼如果你的代碼要用在國(guó)際環(huán)境的話侥钳。Python 默認(rèn)使用 UTF-8 編碼适袜,或者純 ASCII 都能工作得很好。
  • 同樣舷夺,不要在鑒定符使用非 ASCII 字符苦酱,如果只有最輕微的可能會(huì)有不同語(yǔ)言的人閱讀與維護(hù)代碼的話。

數(shù)據(jù)結(jié)構(gòu)

列表

  • list.append(x)

在列表末尾增加元素给猾。等同于 a[len(a):] = [x]

  • list.extend(iterable)

擴(kuò)展列表通過追加來自可迭代對(duì)象中的元素疫萤。等同于a[len(a):] = iterable

  • list.insert(i, x)

在給定位置插入元素。第一個(gè)參數(shù)要插入元素的索引敢伸。所以a,insert(0, x)在列表的最前面插入數(shù)據(jù)扯饶,而a.insert(len(a), x)則等同于 a.append(x)

  • list.remove(x)

刪除列表中第一次出現(xiàn)的值為 x 的數(shù)。如果沒有這個(gè)元素,會(huì)返回錯(cuò)誤帝际。

  • list.pop([i])

刪除列表中給定位置的元素蔓同,然后返回這個(gè)元素。如果沒有說明索引蹲诀,a.pop()會(huì)刪除并返回列表中的最后一個(gè)元素斑粱。(方法中 i 周圍的方括號(hào)說明參數(shù)是可選參數(shù),不是你應(yīng)該在那個(gè)位置敲上方括號(hào)脯爪,你將會(huì)看到這個(gè)記號(hào)在 Python 參考庫(kù)頻繁地出現(xiàn))

  • list.clear()

從列表中刪除全部的元素则北,等同于 del a[:]。a[:]相當(dāng)于是列表a 的淺拷貝痕慢,刪除a[:]就是刪除列表a中所有元素尚揣。如果使用 del a,就相當(dāng)于刪除列表a掖举。

  • list.index(x[,start[,end]])

返回在以零為列表首元素索引的列表中快骗,值為 x 的元素的索引。如果沒有該元素塔次,會(huì)產(chǎn)生 ValueError方篮。

可選參數(shù) start 和 end 用于限定搜索的子序列的開始與結(jié)束點(diǎn)。被返回的索引是相對(duì)于完整序列的開頭而不是由 start 參數(shù)計(jì)算出來的励负。

  • list.count(x)

返回列表中 x 出現(xiàn)的次數(shù)藕溅。0:0

  • list.sort(key=None,reverse=False)

給列表中的元素排序。

  • list.reverse()

逆序继榆。

  • list.copy()

返回 list 的淺拷貝巾表,就相當(dāng)于 a[:]

你可能注意到了,像insert,remove,sort之類的方法只修改 list 中的元素略吨,不返回打印的值------他們只返回 None集币。這是 Python 中所有可變數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)理念。不支持 list.insert(0, 12).remove() 之類的連續(xù)操作翠忠。

作為棧使用

list 的方法使得我們非常輕松就可以把列表當(dāng)作棧使用惠猿,棧中最后被添加的元素是第一個(gè)出棧的元素。在棧的頂部添加元素负间,使用 append。從棧的頂部取走元素姜凄,使用 pop() 方法

作為隊(duì)列使用

我們也可以將列表當(dāng)作隊(duì)列使用政溃,其中先進(jìn)先出。但是态秧,對(duì)于這種情況董虱,列表并不是很高效。盡管在 list 末尾進(jìn)行的 append 和 pop 操作是快速的,但是在列表的頭部插入和刪除數(shù)據(jù)是緩慢的愤诱。因?yàn)槠渌脑匾灰粋€(gè)個(gè)的移動(dòng)云头。

為了補(bǔ)全隊(duì)列,使用·collections.deque淫半,這種方法被設(shè)計(jì)快速而高效地從兩端刪除與添加元素溃槐。

from collections import deque
queue = deque([1,2,3])
queue.append(0)
queue.appendleft(8)

列表推導(dǎo)式

列表推導(dǎo)式提供了一種更簡(jiǎn)潔的方式創(chuàng)建列表。這常用于創(chuàng)建怎樣的新列表呢科吭?通常是列表中的元素是對(duì)其他序列或者可迭代變量的成員進(jìn)行一系列操作的結(jié)果昏滴。或者在一定條件下对人,創(chuàng)建這些元素的子序列谣殊。

squares = [x**2 for x in range(10)]

更加簡(jiǎn)潔,可讀性更強(qiáng)

列表推導(dǎo)式方括號(hào)中的表達(dá)式后面可以加上 for 語(yǔ)句牺弄,然后 0 個(gè)或者更多的 for 或者 if 語(yǔ)句姻几。結(jié)果將會(huì)是一個(gè)新列表,通過 for 或者 if 語(yǔ)句限定得到的表達(dá)式

[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

表達(dá)式是元組必須括起來

# flatten
vec = [[1,2,3], [4,5,6], [7,8,9]]
[num for elem in vec for num in elem]

嵌套列表推導(dǎo)式

列表推導(dǎo)式的第一個(gè)表達(dá)式可以是任意的表達(dá)式势告,包括另一個(gè)列表推導(dǎo)式蛇捌。

[[row[i] for row in matrix] for i in range(4)]
list(zip(*matrix))

del 語(yǔ)句

  • 有一種方式從列表中移除數(shù)值基于他的索引而不是基于他的數(shù)值
  • 這不同于 pop 方法會(huì)返回刪除的值
  • del 語(yǔ)句也被用于從列表中移除切片或者整個(gè)列表
  • del 也可以刪除整個(gè)變量,這時(shí)再引用變量名 a 就會(huì)產(chǎn)生錯(cuò)誤(至少直到它被賦予新的值)

元組與序列

我們看到列表與字符串有許多共同的性質(zhì)培慌,比如索引與切片操作豁陆。他們都是序列數(shù)據(jù)類型。由于 Python 是一種不斷發(fā)展的語(yǔ)言吵护,其他序列數(shù)據(jù)類型也可能被增加盒音。Python 中存在其他標(biāo)準(zhǔn)序列數(shù)據(jù)類型:元組。

元組是由逗號(hào)隔開的值馅而,是不可改變量(immutable)祥诽,但是可以包含列表等可變對(duì)象。

正如你看到的瓮恭,輸出元組總是被括號(hào)包圍雄坪,所以嵌套元組總會(huì)被正確地解釋,盡管通常括號(hào)是不必要的(如果元組是更大表達(dá)式的一部分)屯蹦。不可能給元組單個(gè)元素賦值维哈,但是我們可以創(chuàng)建包含可變對(duì)象的元組。

盡管元組看上去與列表類似登澜,但他們通常被用于不同的場(chǎng)合為了不同的目的阔挠。元組是不可更改的,通常包含不同類型的序列脑蠕,這些序列可以通過解包或者索引來獲取购撼。列表是可變對(duì)象跪削,列表的元素通常是同類型的,可以通過迭代來獲取元素迂求。(元組也可以)

一個(gè)特殊的問題是包含一個(gè)或者零個(gè)元素的元組構(gòu)造:語(yǔ)法有特定的處理來適應(yīng)這些碾盐。空元組由一對(duì)空括號(hào)組成揩局,只有一個(gè)元素的元組毫玖,構(gòu)造為:數(shù)值加上逗號(hào)(將一個(gè)值括起來是不夠的)。很丑谐腰,但是有效孕豹。

解包:t = 1, 2, 3 x, y, z = t

序列解包,適用于右邊所有序列十气。序列解包要求励背,左邊的變量個(gè)數(shù)要與右邊序列元素個(gè)數(shù)相同。注意多變量賦值只是先將序列打包再解包的過程砸西。

集合

  • 無序性
  • 互異性
  • 成員資格測(cè)試和去重
  • 支持?jǐn)?shù)學(xué)操作:并叶眉,交,補(bǔ)芹枷,對(duì)等差分(symmetric difference)
  • 大括號(hào)或者 set 函數(shù)用于產(chǎn)生集合衅疙。
  • 空集,你必須使用 set() 函數(shù)鸳慈,空的大括號(hào){}會(huì)創(chuàng)建空子典
  • fast membership testing : elem in set
  • a - b in a not in b
  • a ^ b in a or b but not both
  • 和列表推導(dǎo)式類似饱溢,集合也支持推導(dǎo)式

a = {x for x in ‘a(chǎn)bracadabra’ if x not in ‘a(chǎn)bc’ }

字典

Python 內(nèi)置的另一個(gè)有用的數(shù)據(jù)類型是字典。字典有時(shí)在其他語(yǔ)言中被認(rèn)為是“associative memories” 或者是“associative arrays”走芋。不像序列可以被一些數(shù)字索引绩郎,字典是通過關(guān)鍵字索引,關(guān)鍵字可以是任何不可變量類型翁逞。字符串與數(shù)字總是可以作為關(guān)鍵字肋杖。元組可以被用作關(guān)鍵字,如果他們只包含字符串挖函、數(shù)字或者元組状植。如果一個(gè)元組直接或者間接地包含任何可變對(duì)象,那么他不可以用作關(guān)鍵字怨喘。你不能使用列表作為關(guān)鍵字津畸,因?yàn)槲覀兛梢允褂盟饕x值、切片賦值或者 append必怜、extend 等方式修改列表元素洼畅。

我們最好認(rèn)為字典是鍵值對(duì)的集合,前提條件是關(guān)鍵字都是互異的棚赔。空的大括號(hào)創(chuàng)建空子典。在大括號(hào)中使用逗號(hào)隔開鍵值對(duì)可以初始化字典靠益,這也是字典在輸出上的寫法丧肴。

字典的主要操作是存儲(chǔ)一些關(guān)鍵字并且基于關(guān)鍵字提取數(shù)值。我們也可以通 del 來刪除鍵值對(duì)胧后。如果你對(duì)一個(gè)已經(jīng)存在的關(guān)鍵字賦值芋浮,那么舊的關(guān)鍵字對(duì)應(yīng)的值將會(huì)被覆蓋。如果你使用不存在的關(guān)鍵字壳快,程序就會(huì)報(bào)錯(cuò)纸巷。

執(zhí)行 list(d) 會(huì)按原有順序返回字典中的所有關(guān)鍵字(如果你只想排序的話,使用 sorted(d) 代替)眶痰。為了檢驗(yàn)單個(gè)關(guān)鍵字是否在字典中瘤旨,我們可以使用 in 這個(gè)關(guān)鍵字。

dict() 可以從其他包含鍵值對(duì)的序列構(gòu)造字典竖伯。

dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
dict([['sape', 4139], ['guido', 4127], ['jack', 4098]])

字典推導(dǎo)式也支持任意的鍵值對(duì)表達(dá)式

{x: x**2 for x in (2, 4, 6)}

如果關(guān)鍵字是簡(jiǎn)單字符串存哲,有時(shí)使用關(guān)鍵字參數(shù)來說明鍵值對(duì)更加方便。

循環(huán)技巧

當(dāng)?shù)值鋾r(shí)七婴,我們通過 items() 方法可以同時(shí)取出關(guān)鍵字與對(duì)應(yīng)值祟偷。

迭代序列,使用 enumerate()打厘,我們可以同時(shí)得到位置索引和對(duì)應(yīng)值修肠。

為了同時(shí)迭代兩個(gè)或者更多的序列,我們可以使用 zip() 函數(shù)户盯。

為了以相反順序迭代嵌施,我們可以使用 reversed() 函數(shù) a[::-1]

為了按照順序迭代序列,使用 sorted() 函數(shù)先舷。該函數(shù)返回一個(gè)新的有序序列艰管,并保持源頭(被拷貝的序列)不變。

當(dāng)你迭代一個(gè)列表時(shí)蒋川,你很有可能改變了列表牲芋,所以更簡(jiǎn)單、更安全的方式是再新建一個(gè)列表捺球。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缸浦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子氮兵,更是在濱河造成了極大的恐慌裂逐,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泣栈,死亡現(xiàn)場(chǎng)離奇詭異卜高,居然都是意外死亡弥姻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門掺涛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庭敦,“玉大人,你說我怎么就攤上這事薪缆⊙砹” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拣帽,是天一觀的道長(zhǎng)疼电。 經(jīng)常有香客問我,道長(zhǎng)减拭,這世上最難降的妖魔是什么蔽豺? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮峡谊,結(jié)果婚禮上茫虽,老公的妹妹穿的比我還像新娘。我一直安慰自己既们,他們只是感情好濒析,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啥纸,像睡著了一般号杏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斯棒,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天盾致,我揣著相機(jī)與錄音,去河邊找鬼荣暮。 笑死庭惜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的穗酥。 我是一名探鬼主播护赊,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼砾跃!你這毒婦竟也來了骏啰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抽高,失蹤者是張志新(化名)和其女友劉穎判耕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翘骂,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壁熄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年帚豪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片请毛。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡志鞍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出方仿,到底是詐尸還是另有隱情,我是刑警寧澤统翩,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布仙蚜,位于F島的核電站,受9級(jí)特大地震影響厂汗,放射性物質(zhì)發(fā)生泄漏委粉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一娶桦、第九天 我趴在偏房一處隱蔽的房頂上張望贾节。 院中可真熱鬧,春花似錦衷畦、人聲如沸栗涂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)斤程。三九已至,卻和暖如春菩混,著一層夾襖步出監(jiān)牢的瞬間忿墅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工沮峡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疚脐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓邢疙,卻偏偏與公主長(zhǎng)得像棍弄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秘症,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容