列表碾平
需求: 將[[1,2],[3,4]]
轉(zhuǎn)換為[1,2,3,4]
,具體實(shí)現(xiàn)有以下幾種方法:
test_list = [[1,2],[3,4]]
1. from itertools import chain
list(chain.from_iterable(test_list))
2. from itertools import chain
list(chain(*test_list))
3. sum(test_list, [])
4. [x for y in test_list for x in y]
5. 遞歸
func = lambda x: [y for t in x for y in func(t)] if type(x) is list else [x]
func(test_list)
PS: 項(xiàng)目中孟岛,難免會(huì)有類似的需求瓶竭,對(duì)于結(jié)構(gòu)嵌套一致的情況,上述的 1渠羞,2斤贰,3,4 方法都 可以很好的解決(不建議用 for 循環(huán)嵌套的方式次询,那是最 low 的方法荧恍,沒有之一);對(duì)于結(jié)構(gòu) 嵌套不一致的情況,第 5 種方法就派上了用場,其采用了遞歸的思想送巡,堪稱萬能的方法摹菠,屢 試不爽。項(xiàng)目中骗爆,大家可以根據(jù)實(shí)際應(yīng)用場景來挑選最適合自己的方法次氨。
三目操作符
代碼參考:
print(1 == 1 and 2 or 3) # 2
print(1 == 2 and 2 or 3) # 3
print(2 if 1 == 1 else 3) # 2
print(2 if 1 == 2 else 3) # 3
PS:習(xí)慣于 if else 的同學(xué)偶爾用下 and or 是不是會(huì)給人耳目一新的感覺。
and or 分開來用
1 and 2 and 3 返回3
1 and 2 and '' 返回''
'' and 2 and 0 返回''
PS:如果都為真則返回最后一個(gè)值摘投,如果其中某些值為假煮寡,則返回第一個(gè)為假的值
1 or '' or 0 返回1
'' or 0 or [] 返回[]
PS:如果都為假返回最后一個(gè)值,如果其中某些值為真犀呼,則返回第一個(gè)為真的值
使用場景:在項(xiàng)目中我們經(jīng)常會(huì)有這樣的需求幸撕,在將一個(gè)字典更新之后還想要返回更新后的 字典,這是我們就可以這樣寫:dic = dic1.update(dic2) or dic1
列表推導(dǎo)式
需求:將列表中每個(gè)元素加1
[x+1 for x in range(1,4)]
PS: 列表推導(dǎo)式底層是用 C 實(shí)現(xiàn)的圆凰,其執(zhí)行速度要比 for 循環(huán)快好多
vars()用法
def func(a, b, c):
print(vars())
func(1, 2, 3) # {"a":1,"b":2,"c":3}
PS:vars()
的值為字典杈帐,其鍵值對(duì)來源于當(dāng)前作用域的所有變量。
使用場景:在調(diào)用他人接口或方法時(shí)专钉,需要將傳入的參數(shù)打印以記錄日志,此刻vars()
便派上用場了累铅。
偏函數(shù)之 partial
import functools
def add(a, b):
return a + b
print(add(4, 2)) # 6
plus3 = functools.partial(add, 3)
print(plus3(1)) # 4
使用場景: 當(dāng)我們需要同時(shí)去調(diào)用一個(gè)函數(shù)跃须,并且發(fā)現(xiàn)大部分參數(shù)一致的時(shí)候,便可以采取上述方法娃兽,一來代碼簡潔菇民,二來可讀性高。
Python 搭建簡易服務(wù)
- Python 搭建簡易郵件服務(wù)器
python -m smtpd -n -c DebuggingServer localhost:1025
- Python 搭建簡易 web 服務(wù)器
- Python2:
python -m SimpleHTTPServer port
- Python3:
python -m http.server port
- Python2:
- Python 搭建簡易 ftp 服務(wù)
- pip install pyftpdlib
- python -m pyftpdlib -p 21
- ftp://localhost:21
內(nèi)存管理
Python 的內(nèi)存管理主要分為引用計(jì)數(shù)和垃圾回收機(jī)制兩大部分投储,且看下面代碼:
內(nèi)存分配
a = 1
b = 1
a is b # True
a = 10000
b = 10000
a is b # False
在 Python 中第练,整數(shù)和短小的字符,解釋器都會(huì)緩存這些對(duì)象玛荞,以便重復(fù)使用娇掏。
當(dāng)我們創(chuàng)建多個(gè)等于 1 的引用時(shí),實(shí)際上是讓這些引用指向了同一個(gè)對(duì)象勋眯。
引用計(jì)數(shù)
在 Python 中婴梧,所謂引用計(jì)數(shù)(reference count)是指所有指向該對(duì)象的引用的總數(shù);
我們可以使用 sys 包中的 getrefcount(),來查看某個(gè)對(duì)象的引用計(jì)數(shù)客蹋。需要注意的是塞蹭,當(dāng)使用該函數(shù)查看某個(gè)對(duì)象的引用計(jì)數(shù)時(shí),實(shí)際上是臨時(shí)創(chuàng)建了該對(duì)象的一個(gè)新的引用讶坯,所有使用 getrefcount()所得到的結(jié)果番电,會(huì)比期望的值多 1。
from sys import getrefcount
aa = 'test refcount'
print(getrefcount(a))
bb = aa
print(getrefcount(a))
引用減少
引用減少大致分為兩類:
-
指向該對(duì)象的引用指向了其他對(duì)象
from sys import getrefcount aa = 'test refcount' bb=aa print(getrefcount(aa)) # 3 bb=1 print(getrefcount(aa)) # 2
-
使用del關(guān)鍵字顯示的刪除某個(gè)引用
from sys import getrefcount aa = 'test refcount' bb=aa print(getrefcount(aa)) # 3 del bb print(getrefcount(aa)) # 2
垃圾回收
不斷的創(chuàng)建對(duì)象辆琅,如果不及時(shí)銷毀的話漱办,那 Python 的體積會(huì)越來越大这刷,再大的內(nèi)存也會(huì)有耗完的時(shí)候;不用像 C 語言那樣,需要手動(dòng)的去管理內(nèi)存洼冻、Python 已經(jīng)幫我們做好了(Python 的垃圾回收機(jī)制)崭歧,你只需要去關(guān)心你的業(yè)務(wù)邏輯即可,其他的都交給 Python 來處理撞牢。
從原理上講率碾,當(dāng) Python 中某個(gè)對(duì)象的引用計(jì)數(shù)降為 0 時(shí),該對(duì)象就應(yīng)該被回收屋彪。但是頻繁的啟動(dòng)垃圾回收機(jī)制畢竟是個(gè)很耗時(shí)的問題;因此 Python 只有在特定條件下(當(dāng) Python 中被分配對(duì)象和取消分配對(duì)象的次數(shù)之間的差值達(dá)到某個(gè)閾值時(shí))所宰,Python會(huì)自動(dòng)啟動(dòng)垃圾回收機(jī)制。
我們可以通過 gc 模塊的 get_threshold()方法畜挥,查看該閾值:
import gc
print(gc.get_threshold())
該方法會(huì)返回(700, 10, 10)仔粥,后面的倆 10 是與分代回收相關(guān)的,稍后講解蟹但。700 便是垃圾回收機(jī)制啟動(dòng)的閾值躯泰。可以通過 gc 模塊中的 set_threshold()方法重新設(shè)定該值华糖。
當(dāng)然了麦向,我們也可以手動(dòng)啟動(dòng)垃圾回收機(jī)制,使用 gc.collect()即可客叉。
分代回收
Python 同時(shí)采用了分代回收的機(jī)制诵竭,設(shè)想一下:存活越久的對(duì)象、越不可能是垃圾對(duì)象兼搏。程序在運(yùn)行時(shí)卵慰,往往會(huì)產(chǎn)生大量的臨時(shí)對(duì)象,程序結(jié)束之后佛呻,這些臨時(shí)對(duì)象的生命周期也就隨之告一段落裳朋。但有一些對(duì)象會(huì)被長期占用,垃圾回收機(jī)制在啟動(dòng)的時(shí)候會(huì)減少掃??到他們的頻率件相。
Python 將所有對(duì)象分為 0再扭,1,2 三代夜矗。所有新創(chuàng)建的對(duì)象都是 0 代泛范,當(dāng)垃圾回收機(jī)制在啟動(dòng)多次 0 代機(jī)制并掃??到他們的時(shí)候,這些對(duì)象如果依然存活在內(nèi)存的話紊撕,他們就會(huì)被歸入下一代對(duì)象罢荡,以此類推。
剛才上面所??到的(700, 10, 10),700為垃圾回收啟動(dòng)的閾值(即對(duì)象的分配次數(shù)和釋放次數(shù)的差值)区赵,后面的倆 10 所代表的意思是:每 10 次 0代垃圾回收惭缰,會(huì)配合 1 次 1 代的垃圾回收;而每 10 次 1 代的垃圾回收會(huì)配合 1 次的2 代垃圾回收。
當(dāng)然我們同樣可以使用 set_threshold()來調(diào)整此策略的比例笼才,比如對(duì) 1 代對(duì)象進(jìn)行更頻繁的掃描漱受。
import gc
gc.set_threshold(700, 5, 10)
gc.get_count()
會(huì)返回當(dāng)前垃圾回收狀態(tài):
- 當(dāng)計(jì)數(shù)器從(699,0,0)增加到(700,0,0),gc模塊就會(huì)執(zhí)行
gc.collect(0)
骡送,即檢查0代對(duì)象的垃圾昂羡,并重置計(jì)數(shù)器為(0,1,0) - 當(dāng)計(jì)數(shù)器從(699,9,0)增加到(700,9,0),gc模塊就會(huì)執(zhí)行
gc.collect(1)
摔踱,即檢查0,1代對(duì)象的垃圾虐先,并重置計(jì)數(shù)器為(0,0,1) - 當(dāng)計(jì)數(shù)器從(699,9,9)增加到(700,9,9),gc模塊就會(huì)執(zhí)行
gc.collect(2)
派敷,即檢查0,1,2代對(duì)象的垃圾蛹批,并重置計(jì)數(shù)器為(0,0,0)。