Python 板


LINE

1F:→ SocketAM2:u = [min(s[i], t[i]) for i in range(len(s))] 08/01 01:35
2F:→ SocketAM2:我發現我的第一感好像跟上面的各位很不一樣...... 08/01 01:36
3F:→ SocketAM2:有大大可以點評一下大家的第一感的優劣之處嗎? 08/01 01:36
4F:→ SocketAM2:個人覺得mikapauli的"list(map(min, s, t))"是目前最優 08/01 01:37
5F:→ SocketAM2:除了簡潔(不熟map就不直覺XD)外,我猜執行效率是最優的 08/01 01:39
6F:→ SocketAM2:看了下mikapauli大在原PO上一篇的推文自以為效率也很高 08/01 01:42
直覺這種東西本來就很主觀, 重點是不能為了直覺犧牲太多效率 需要會最少東西的寫法應該是 result = [] for i in range(0, len(s)): # 陣列很長時應改用 xrange if s[i] > t[i]: result.append(t[i]) else: result.append(s[i]) 當然這基本上是 O(n) 所以大方向對了, 不過還是有幾個問題 1. 做了 len(s) 次 index lookups Subscript syntax 基本上是做 random access, 速度不如 iterator 當次數大時效率會有明顯落差 2. 對不等長陣列的支援不好, 如果要加上更多判斷, 可讀性會慢慢下降 3. 出來的東西只能是陣列, 如果你之後還要 iterate 它, 等於做了白工多轉換一次 4. 擴充性不佳, 例如如果以後要多比較一個陣列 r 就會炸裂 針對最後一點, 所以我們必須學習內建的 min 和 max 這裡可以用 min 來改寫 result = [] for i in range(len(s)): # 只給一個參數就預設是從 0 開始 result.append(min(s[i], t[i])) 事實上我覺得即使初學者, 最低限度也要寫成這樣, 更差的都不及格 第三點可以改成 generator 或輸出 iterator 來解決 例如包成 generator... def generate_mins(list1, list2): for i in range(len(list1)): yield min(list1[i], list2[i]) result = generate_mins(s, t) 不過 yield 算進階語法, 為了不用更常用的語法而先學是本末倒置, 所以跳過 另外一種產生方法就等於要學 list comprehension 了 result = (min(s[i], t[i]) for i in range(0, len(s))) 只差在有沒有在這裡直接轉成 list (改用方括弧而非原括弧包起來) 而已 第二點稍後討論, 先講第一點 寫資料處理的程式時, iteration 的速度基本上決定了你的程式價值 即使再怎麼優美或容易維護或怎樣, 你處理速度慢人家超過一定程度就等於垃圾 所以各種語言才會用各式各樣的方法為非連續記憶體的 list loop-through 加速 Python (和其他很多語言) 的做法就是使用 foreach 語法 寫 for i in a_list: i 效率就是會優於 for i in range(a_list): a_list[i] 所以我們要做的是想辦法同時 iterate 複數個 lists, 而不是改用 suubscription Python 提供的解決方案就是 zip 與自動 tuple 展開 所以繼續改寫... result = (min(i[0], i[1]) for i in zip(s, t)) 自動展開 result = (min(a, b) for a, b in zip(s, t)) 這樣就有基本的樣子了 或者 如果你了解到其實 min 其實可以直接吃 iterable... result = (min(i) for i in zip(s, t)) 關於第二點, zip 有一個額外性質是會自動 trim-up 當輸入的 lists 不等長, 會自動把多的丟掉 如果你不喜歡這個行為, 而希望當某個 list 不夠長時提供預設值 則可以使用 itertools module 裡的 izip_longest from itertools import izip_longest result = (min(i) for i in izip_longest(s, t, float('inf'))) float('inf') 會產生「無窮大」, 所以這等於如果有陣列不夠長就無視它 順帶一題, 如果輸入陣列太長, zip 也有可能會有速度問題 這時候可以改用 itertools 的 izip 這樣我們就有了一個效率很好, 可讀性也優良的寫法 大部分人也都是這樣推薦 ====== 前面有人提出 map 的寫法 map(min, zip(s, t, u)) 這也合理, 不過 map 在 Python 3 的行為有改, 要注意 Python 基本上比較不喜歡這類 function-oriented 的語法 這是 Guido 的個人偏好... -- 「我最想要的同伴嘛,首先是要笑口常開,其次是我們能永遠不會發生誤會。 如果這些都能辦到的話,嗯,如果他是世界上第一流的橋手,也還不錯。」 -- 班尼多‧加羅素,前義大利藍隊成員 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.94.61
7F:推 tiefblau:好文推 08/01 11:48
8F:→ drm343:python 的 map 跟 scheme 相同,zip 是不需要的 08/01 12:08
9F:推 vvind:受教了 08/01 12:40
10F:推 MAGICXX:推這篇! 08/01 12:51
11F:推 lc85301:這種有歷史跟程式概念的東西要從哪裡學lol 08/01 12:53
12F:推 TuTu522:推 08/01 14:03
※ 編輯: uranusjr 來自: 140.112.94.61 (08/01 14:42)
13F:推 timTan:Push~~ 08/01 17:01
14F:推 timTan:歷史的部份,有愛就會有阿~ 08/01 17:12
15F:→ timTan:有愛自然會常常看 Relase Note 跟 PEP, 就會知道很多事情。 08/01 17:12







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job站內搜尋

TOP