5

在 Python 中,我真的很享受使用列表推导时实现的简洁性。我喜欢做简洁的列表理解:

myList = [1, 5, 11, 20, 30, 35] #input data
bigNumbers = [x for x in myList if x > 10]

但是,我经常遇到像这样更冗长的实现:

myList = [1, 5, 11, 20, 30, 35] #input data
bigNumbers = []
for i in xrange(0, len(myList)):
    if myList[i] > 10:
        bigNumbers.append(myList[i])

当 afor loop只查看一个数据结构(例如myList[])时,通常有一个直接的列表理解语句,它等效于循环。
考虑到这一点,是否有一个重构工具可以将冗长的 Python 循环转换为简洁的列表理解语句?


以前的 StackOverflow 问题已要求有关将循环转换为列表理解的建议。但是,我还没有找到关于自动将循环转换为列表理解表达式的问题。


动机:有很多方法可以回答“代码干净意味着什么?”这个问题。就个人而言,我发现使代码简洁并消除一些绒毛往往会使代码更清晰和更具可读性。在“简洁的代码”和“难以理解的单行代码”之间自然有一条界限。尽管如此,我经常发现编写和使用简洁的代码是令人满意的。

4

1 回答 1

5

2to3是一种重构工具,可以执行任意重构,只要您可以使用语法模式指定它们即可。您可能想要寻找的模式是这个

VARIABLE1 = []
for VARIABLE2 in EXPRESSION1:
    if EXPRESSION2:
        VARIABLE1.append(EXPRESSION3)

这可以安全地重构为

VARIABLE1 = [EXPRESSION3 for VARIABLE2 in EXPRESSION1 if EXPRESSION2]

在您的具体示例中,这将给出

bigNumbers = [myList[i] for i in xrange(0, len(myList)) if myList[i] > 10]

然后,您可以进行另一次重构,将 xrange(0, N) 替换为 xrange(N),并进行另一次重构

[VARIABLE1[VARIABLE2] for VARIABLE2 in xrange(len(VARIABLE1)) if EXPRESSION1]

[VARIABLE3 for VARIABLE3 in VARIABLE1 if EXPRESSION1PRIME]

这种重构有几个问题:

  • EXPRESSION1PRIME必须用 VARIABLE3 替换EXPRESSION1所有出现的 。VARIABLE1[VARIABLE2]这对于 2to3 是可能的,但需要显式代码来执行遍历和替换。
  • EXPRESSION1PRIMEthen 不能再包含 VARIABLE1. 这也可以使用显式代码进行检查。
  • 需要为 VARIABLE3 命名。你选择了x;没有合理的方法可以自动完成此操作。您可以为此选择回收VARIABLE1(即i),但这可能会令人困惑,因为它表明它i仍然是一个索引。它可能会选择一个合成名称,例如VARIABLE1_VARIABLE2(ie myList_i),并检查是否未使用其他名称。
  • 需要确保 VARIABLE1[VARIABLE2] 产生的结果与使用iter(VARIABLE1). 不可能自动执行此操作。

如果您想学习如何编写 2to3 修复程序,请查看Lennart Regebro 的书。

于 2013-01-25T14:56:56.507 回答