用于非平凡列表推导的惯用Python

时间:2014-12-10 16:12:29

标签: python idiomatic

使用列表解析以异步方式实现对Python中的iterable执行简单转换:

y = [f(arg) for arg in args]

其中fsimple statement,如果map是命名函数,则为f

y = map(f, args)

Guido favors list comprehensions超过map(lambda x:..., args),确实列出了对mapfilter at all使用情况的理解。

但是,我不清楚我应该如何解决以下问题:

  • 修改可迭代的每个元素
  • 以非平凡的方式,
  • 使用一段独立的逻辑(可能是一个函数),
  • 在其他任何地方都不是很有用

解决此类问题的最惯用方法是什么? 我已经看过并尝试过的一些我已经参与过的Python项目:

Predeclare和loop

显而易见的方法是预先声明输出和循环:

def transform(...):

    ...

    y = []
    for arg in args:
        first_statement
        second_statement
        ...
        y.append(statement)

评论:

  • (亲)易于遵循逻辑
  • (con)逻辑没有作用域(泄漏抽象)
  • (con)逻辑不明确(你怎么知道它是一个地图而没有检查循环中所有分支的运作方式?)
  • (con)以一种无用的方式不必要地预先声明变量(y必须与args的长度相同)

嵌套函数

另一个选择是将逻辑封装在嵌套函数中,然后使用map或list comprehension调用它:

def transform(...):

    ...

    def anonymous(arg):
        first_statement
        second_statement
        ...
        return statement

    y = map(anonymous, args)
    # y = [anonymous(arg) for arg in args]

评论:

  • (专业版)封装逻辑
  • (专业版)可以访问外部范围
  • (专业版)无法修改外部范围(明确表示没有副作用)
  • (Con)每次调用内部函数时都会重新定义
  • (Con)内部函数没有真实姓名(在地图范围内应该是匿名的)

外部功能

将内部函数移动到外部范围解决了其中一些问题,但引入了更多:

def _anonymous(arg):
    first_statement
    second_statement
    ...
    return statement

def transform(...):

    ...

    y = map(_anonymous, args)

评论:

  • (Pro):函数在分析时编译一次
  • (Con):对于一小段逻辑,函数离调用站点太远(导致程序员不必要的上下文切换)
  • (Con):函数无法访问外部作用域。必须传递任何要求(阻止使用map)或partial ized

摘要

我很矛盾。你如何解决你需要做一个非平凡的丢弃地图的问题?

0 个答案:

没有答案