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灯, 水草

请输入看板名称,例如:BabyMother站内搜寻

TOP