用于非平凡列表理解的惯用Python

2024-05-15 08:54:44 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中对iterable执行简单的转换通常是通过列表理解来实现的:

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

其中fsimple statement,或者是函数{},如果{}是命名函数:

^{pr2}$

Guido favors list comprehensions超过map(lambda x:..., args),并且确实列出了对map或{}at all用法的理解。在

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

  • 在每个元素中修改
  • 以非常重要的方式
  • 使用一个离散的逻辑(可以是一个函数)
  • 这在其他地方都没用

解决这类问题最惯用的方法是什么? 在我参与的Python项目中,我看到并尝试了一些事情:

预分解和循环

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

def transform(...):

    ...

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

评论:

  • (pro)易于遵循逻辑
  • (con)逻辑没有作用域(泄漏抽象)
  • (con)逻辑不明确(如果不检查循环中所有分支的操作方式,如何知道它是一个映射?)在
  • (con)以不必要的方式预先声明变量(y必须与args的长度相同)

嵌套函数

另一种选择是将逻辑封装在嵌套函数中,然后使用映射或列表理解来调用它:

def transform(...):

    ...

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

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

评论:

  • (Pro)封装逻辑
  • (Pro)可以访问外部范围
  • (Pro)无法修改外部范围(明确表示没有副作用)
  • (Con)每次调用内部函数时都会重新定义它
  • (Con)内部函数没有实名(应该在映射范围内匿名)

外部功能

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

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

def transform(...):

    ...

    y = map(_anonymous, args)

评论:

  • (Pro):函数在解析时编译一次
  • (Con):对于一小部分逻辑来说,函数离调用位置太远(导致程序员不必要的上下文切换)
  • (Con):函数不能访问外部范围。任何要求都必须传入(防止使用map)或partial

摘要

我很矛盾。当你需要做一个非平凡的一次性地图时,你如何解决问题?在


Tags: 函数inmapfordef方式argargs