【问题标题】:filter and map in one? (Python)过滤和映射合二为一? (Python)
【发布时间】:2013-12-04 21:43:41
【问题描述】:

问题:

def detect_monitors_and_modes(preferred_order, binp):
    out = run_xrandr(binp)
    findit = partial(get_mon_mode, preferred_order)
    print 'OUTPUT', '\n'.join(out)
    lst = map(findit, out)
    print 'lst', lst
    matches = filter(lambda x: x, lst)
    print 'matches', matches


OUTPUT Screen 0: minimum 320 x 200, current 1366 x 768, maximum 8192 x 8192
LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 194mm
   1366x768       60.1*+   40.1
   1360x768       59.8     60.0
   1024x768       60.0
   800x600        60.3     56.2
   640x480        59.9
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)

lst [None, 'LVDS1', '1366x768', None, None, None, None, None, None, None, None]
matches ['LVDS1', '1366x768']

具体来说,我想知道是否有更短/更惯用的方法来做到这一点:

lst = map(findit, out)
matches = filter(lambda x: x, lst)

显然,我不能只使用filter bc 这将返回整行 (LVDS1 connected 1366x768+0+0 (normal...) 而不是 findit 返回的值。对于不匹配的行,map 返回 Nones。

reduce 在这里有什么用处吗?但因为它不是犹太洁食……)

编辑:我想在这里过滤掉“虚假”值,即空字符串、Nones、False 等等,只留下findit 找到的正匹配。

【问题讨论】:

    标签: python map filter


    【解决方案1】:

    我想在这里过滤掉“假”值,即空字符串、无、假等,只留下 findit 找到的作为正匹配。

    你可以简化为:

    matches = filter(None, map(findit, out))
    

    根据文档:

    如果functionNone,则假定恒等函数,即iterable中所有为假的元素都被移除。

    供参考:

    【讨论】:

    • 我觉得我更喜欢filter(bool, map(findit, out)),因为它感觉不如None快捷方式那么神奇。
    • 如果您愿意,也可以使用列表解析[x for x in map(findit, out) if x]。但我认为map() 周围没有理智的方法。
    【解决方案2】:

    是的,使用列表推导

    matches = [findit(x) for x in out if findit(x) is not None]
    

    这是 PEP 所描述的“pythonic”方式

    【讨论】:

    • 我不确定这是否真的是 Pythonic - 两次(不必要地)执行 findit(x) 违反了 DRY。
    • 为了避免这种重复,[y for x in out for y in [findit(x)] if y is not None],尽管这并没有真正显示出最好的列表理解。我有一段时间没有使用 Python,但这应该可以工作 - 基本上是迭代一个单项列表以绑定该变量。可能有更好的方法,但我不记得了。
    • @Steve:我喜欢列表推导,但这是推动它。 ;-) (我认为省略is not None 部分可以做得更好)
    • @John Doe - 总是有[x for x in [findit(y) for y in out] if x is not None] - 地图+过滤器版本的相当直接的音译。我不记得为什么is not None 在那里而且我懒得解决它,所以它留在里面(这个短语解释了大约 90% 的旧代码和至少 99.9% 的 cmets)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 2022-07-06
    • 2017-12-22
    • 2016-08-22
    • 2019-09-04
    • 2015-11-20
    • 2020-11-23
    相关资源
    最近更新 更多