Python 解析式、生成器

一丁频、標準庫 datetime

1.1 datetime 模塊
  • 對日期、時間邑贴、時間戳的處理
1.2 datetime
  • 類方法
    a. today() 返回本地時區(qū)當前時間的 datetime 對象
    b. now(tz=None) 返回當前時間的 datetime 對象席里,精確至微秒,若 tzNone拢驾,返回同 today()
    c. utcnow() 沒有時區(qū)的當前時間
    d. fromtimestamp(timestamp, tz=None) 從一個時間戳返回一個 datetime 對象
1.3 datetime 對象
  • timestamp() 返回一個到微秒的時間戳
    a. 時間戳:格林威治時間 1970 年 1 月 1 日 0 點到現(xiàn)在的秒數(shù)

  • 構(gòu)造方法 datetime.datetime(2020, 12, 6, 16, 29, 43, 79043)

  • year奖磁、monthday繁疤、hour咖为、minutesecond嵌洼、microsecond案疲,取 datetime 對象的年月日時分秒及微秒

  • weekday() 返回周幾,周一為 0麻养,周日為 6

  • isoweekday() 返回周幾褐啡,周一為 1,周日為 7

  • date() 返回日期 date 對象

  • time() 返回時間 time 對象

  • replace() 修改并返回新的時間

  • isocalendar(0 返回一個三元組(年鳖昌,周數(shù)备畦,周幾)

1.4 日期格式化
  • 類方法 strptime(date_string, format),返回 datetime 對象

  • 對象方法 strftime(format)许昨,返回字符串

  • 字符串 format 函數(shù)格式化

import datetime

dt = datetime.datetime.strptime("08/12/20 16:30", "%d/%m/%y %H:%M")

print(dt.strftime("%Y-%m-%d %H:%M:%S"))
print("{0:%Y}/{0:%m}/{0:%d} {0:%H}::{0:%H}::{0:%S}".format(dt))
print('{:%Y-%m-%d %H:%M:%S}'.format(dt))
示例.png
1.5 timedelta 對象
  • datetime2 = datetime1 + timedelta
  • datetime2 = datetime1 - timedelta
  • timedelta = datetime1 - datetime2
  • 構(gòu)造方法
    a. datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
    b. year = datetime.timedelta(days=365)
  • total_seconds() 返回時間差的總秒數(shù)

二懂盐、標準庫 time

2.1 time
  • time.sleep(secs) 將調(diào)用線程掛起指定的秒數(shù)

三、列表解析

3.1 舉例
  • 生成一個列表糕档,元素 0 ~ 9莉恼,對每一個元素自增 1 后求平方返回新列表
lst = list(range(10))
newlst = list()

for i in lst:
    newlst.append((i+1) ** 2)
print(newlst)


lst = list(range(10))
newlst = [ (i + 1) ** 2 for i in lst]
print(newlst)
示例.png
3.2 語法
  • [ 返回值 for 元素 in 可迭代對象 if 條件]
  • 使用中括號 [],內(nèi)部是 for 循環(huán)速那,if 條件語句可選
  • 返回一個新列表
3.3 列表解析式是一種語法糖
  • 編譯器會優(yōu)化俐银,不會因為簡寫而影響效率,反而因優(yōu)化提高了效率
  • 減少程序員工作量端仰,減少出錯
  • 簡化了代碼捶惜,但可讀性增強
3.4 舉例
  • 獲取 10 以內(nèi)的偶數(shù),比較執(zhí)行效率
even = []

for i in range(10):
    if i % 2 == 0:
        even.append(i)

even = [ i for i in range(10) if i % 2 == 0]
示例.png
  • 思考
    1. 有這樣的賦值語句 newlist = [print(i) for i in range(10)]荔烧,請問打印出什么吱七?newlist 打印出來是什么汽久?

      示例.png

    2. 獲取 20 以內(nèi)的偶數(shù),若同時 3 的倍數(shù)也打印 [i for i in range(20) if i % 2 == 0 elif i % 3 ==0] 行么踊餐?

      示例.png

四景醇、列表解析進階

4.1 [expr for item in iterable if cond1 if cond2]
  • 等價于
ret = []

for item in iterable:
    if cond1:
        if cond2:
            ret.appent(expr)
  • 舉例
    • 20 以內(nèi),既能被 2 整除又能被 3 整除的數(shù)
    [i for i in range(20) if i %2 == 0 and i % 3 == 0]
    
    [i for i in range(20) if i 5 2 == 0 if i % 3 == 0]
    
示例.png
4.2 [expr for i in iteranle1 for j in iterable2]
  • 等價于
ret = []

for i in iterable1:
    for j in iterable2:
        ret.append(expr)
  • 舉例
    [(x, y) for x in 'abcde' for y in range(3)]
    [[x, y] for x in 'abcde' for y in range(3)]
    [{x, y} for x in 'abced' for y in range(3)]   # 集合是整個生成列表中的元素市袖,不會去重
    [{x: y} for x in 'abced' for y in range(3)]   # 字典與集合相同啡直,不會去重
    
示例.png
示例.png
示例.png
示例.png
4.4 請問下面 3 中輸出各是什么?為什么
[(i,j) for i in range(7) if i>4 for j in range(20,25) if j>23]
[(i,j) for i in range(7) for j in range(20,25) if i>4 if j>23]
[(i,j) for i in range(7) for j in range(20,25) if i>4 and j>23]
示例.png

五苍碟、列表解析練習

5.1 練習(要求使用列表解析式完成)
  • 返回 1 - 10 平方的列表
[i ** 2 for i in range(11) if i > 0 ]
示例.png
  • 有一個列表 lst = [1, 4, 9, 16, 2, 5, 10, 15]酒觅,生成一個新列表,要求新列表元素是 lst 相鄰 2 項的和
lst = [1, 4, 9, 16, 2, 5, 10, 15]
[lst[i] + lst[i+1] for i in range(len(lst)) if i < (len(lst)-1)]
示例.png

六微峰、生成器表達式 Generator expression

6.1 語法
  • (返回值 for 元素 in 可迭代對象 if 條件)
  • 列表解析式中的括號換成小括號即可
  • 返回一個生成器
示例.png
6.2 和列表解析式的區(qū)別
  • 生成器表達式是 按需計算(或稱 惰性求值舷丹、延遲計算),需要的時候才計算值
  • 列表解析式是立即返回值
示例.png
6.3 生成器
  • 可迭代對象
  • 迭代器
示例.png
6.4 舉例
g = ("{:04}".format(i) for i in range(1,11))
next(g)
for x in g:
    print(x)
print('~~~~~~~~~~~~')
for x in g:
    print(x)
  • 列表對比
g = ["{:04}".format(i) for i in range(1,11)]
for x in g:
    print(x)
print('~~~~~~~~~~~~')
for x in g:
    print(x)
6.5 總結(jié)
  • 生成器

    1. 延遲計算
    2. 返回迭代器蜓肆,可迭代
    3. 從前到后走完一遍颜凯,不能回頭
  • 列表

    1. 立即計算
    2. 返回的不是迭代器,返回可迭代對象列表
    3. 從前導后走完一遍仗扬,可重新回頭迭代
6.6 習題
it = (print("{}".format(i+1)) for i in range(2))
first = next(it)
second = next(it)
val = first + second
  • val 的值是什么
print() 函數(shù)是立即返回症概,所以不論是 first 還是 second 的值都是 None
所以 val 的運算結(jié)果會拋異常
示例
  • val = first + second 語句之后能否再次 next(it)
不可以 next() 了,因為此前的計數(shù)器是 range(2)早芭,程序已經(jīng)迭代兩次彼城,所以不可再次 next()
示例.png
it = (x for x in range(10) if x % 2)
first = next(it)
second = next(it)
val = first + second
  • val 的值是什么?
val 的值為 4
示例.png
  • val = first + second 語句后能否再次 next(it)
因為此前計數(shù)器并未迭代完退个,所以可以繼續(xù) next() 調(diào)用
示例.png
6.7 和列表解析式的對比
  • 計算方式
    1. 生成器表達式延遲計算募壕,列表解析式立即計算
  • 內(nèi)存占用
    1. 單從返回值本身來說,生成器表達式
    2. 生成器沒有數(shù)據(jù)语盈,內(nèi)存占用極少舱馅,它是使用時一個個返回數(shù)據(jù),若將這些返回的數(shù)據(jù)合起來占用的內(nèi)存和列表解析式差不多刀荒,但是代嗤,它不需要立即占用這么多內(nèi)存
    3. 列表解析式構(gòu)造新的列表需要立即占用內(nèi)存,不管你是否立即使用這么多數(shù)據(jù)
  • 計算速度
    1. 但看計算時間缠借,生成器表達式耗時非常短资溃,列表解析式耗時長
    2. 但生成器本身并沒有返回任何值,只返回了一個生成器對象
    3. 列表解析式構(gòu)造并返回了一個新的列表烈炭,所以開起來耗時了

七、集合解析式

7.1 語法
  • { 返回值 for 元素 in 可迭代對象 if 條件 }
  • 列表解析式的中括號換成大括號 {} 即可
  • 立即返回一個集合
7.2 用法
  • {(x, x+1) for x in range(10)}

  • {[x] for x in range(10)}

八宝恶、字典解析式

8.1 語法
  • { 返回值 for 元素 in 可迭代對象 if 條件 }
  • 列表解析式中的括號換成大括號 {} 即可
  • 使用 key:value 形式
  • 立即返回一個字典
8.2 用法
  • {x:(x, x+1) for x in range(10)}
  • {x:[x, x+1] for x in range(10)}
  • {(x,):[x, x+1] for x in range(10)}
  • {[x]:[x, x+1] for x in range(10)}
  • {chr(0x41 +x):x**2 for x in range(10)}
  • {str(x):y for x in range(3) for y in range(4)}
  • 等價于
ret = {}
for x in range(3):
    for y in range(4):
        ret[str(x)] = y

九符隙、總結(jié)

  • Python 2 引入列表解析式
  • Python 2.4 引入生成器表達式
  • Python 3 引入集合趴捅、字典解析式,并遷移至 Python 2.7
  • 一般來說霹疫,應該多應用解析式拱绑,簡短、高效
  • 若一個解析式非常復雜丽蝎,難以讀懂猎拨,可考慮拆解成 for 循環(huán)
  • 生成器和迭代器是不同的對象,但都是可迭代對象
  • 可迭代對象范圍更大屠阻,都可使用 for 循環(huán)遍歷
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末红省,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子国觉,更是在濱河造成了極大的恐慌吧恃,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麻诀,死亡現(xiàn)場離奇詭異痕寓,居然都是意外死亡,警方通過查閱死者的電腦和手機蝇闭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門呻率,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呻引,你說我怎么就攤上這事礼仗。” “怎么了苞七?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵藐守,是天一觀的道長。 經(jīng)常有香客問我蹂风,道長卢厂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任惠啄,我火速辦了婚禮慎恒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撵渡。我一直安慰自己融柬,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布趋距。 她就那樣靜靜地躺著粒氧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪节腐。 梳的紋絲不亂的頭發(fā)上外盯,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天摘盆,我揣著相機與錄音,去河邊找鬼饱苟。 笑死孩擂,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的箱熬。 我是一名探鬼主播类垦,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼城须!你這毒婦竟也來了蚤认?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酿傍,失蹤者是張志新(化名)和其女友劉穎烙懦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赤炒,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡氯析,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了莺褒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掩缓。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖遵岩,靈堂內(nèi)的尸體忽然破棺而出你辣,到底是詐尸還是另有隱情,我是刑警寧澤尘执,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布舍哄,位于F島的核電站,受9級特大地震影響誊锭,放射性物質(zhì)發(fā)生泄漏表悬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一丧靡、第九天 我趴在偏房一處隱蔽的房頂上張望蟆沫。 院中可真熱鬧,春花似錦温治、人聲如沸饭庞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舟山。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捏顺,已是汗流浹背六孵。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留幅骄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓本今,卻偏偏與公主長得像拆座,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子冠息,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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