自动简化/重构Python代码(例如for循环->列表推导式)?

6
在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])

当一个 for 循环 只遍历一个数据结构(例如 myList[])时,通常有一个简单的列表推导式语句等同于循环。
有没有一种重构工具,将冗长的 Python 循环转换为简洁的列表推导式?

之前的 StackOverflow 问题 寻求了将循环转换为列表推导式的建议。但是,我还没有找到一个关于自动将循环转换为列表推导式表达式的问题。


动机: 有多种方法来回答“代码何时算干净?” 的问题。个人而言,我发现让代码简洁并摆脱一些废话往往会使代码更加简洁易读 。当然,“简洁代码”和“难以理解的一行代码”的界限也存在。尽管如此,我经常觉得编写和使用简洁的代码非常令人满意。

这也是我会做的事情。不幸的是,我看到很多不必要冗长的代码就像这样。是否有重构工具可以将 xrange(0, len(myList)) 替换为 enumerate(myList)?当试图清理别人的代码或尝试将一些混乱的代码转换为可用于教程的东西时,这将特别有用。 - solvingPuzzles
1
@AshwiniChaudhary,或者只需使用for elem in myList: - jimhark
1
`What is Pythonic?"for i in range(len(seq)):"? No.Use "for obj in seq:".` - PaulMcG
@solvingPuzzles 我做了一些谷歌搜索,但似乎找不到任何可以修改源代码的东西,使while循环变成for循环或LC。所有的内容都与分析和静态代码分析有关。 - Ashwini Chaudhary
1
我也喜欢编写简洁的代码,但同时也希望保持可读性。手动将循环转换为列表推导式并不难,我不会相信工具来完成这个任务。 - Martijn Pieters
4
自动完成这个任务的一种方法是使用 urllib 在 Stack Overflow 上发布一个问题,等待 2-3 分钟,然后下载回答。 - georg
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必须是EXPRESSION1,其中所有出现的VARIABLE1[VARIABLE2]都被替换为VARIABLE3。这可以通过2to3实现,但需要显式代码来进行遍历和替换。
  • EXPRESSION1PRIME不能再包含VARIABLE1的任何其他出现。这也可以通过显式代码进行检查。
  • 需要为VARIABLE3想出一个名称。您选择了x;没有合理的自动完成方式。您可以选择回收VARIABLE1(即i)来实现这一点,但这可能会令人困惑,因为它表明i仍然是一个索引。可能会选择一个合成名称,例如VARIABLE1_VARIABLE2(即myList_i),并检查是否没有其他地方使用。
  • 需要确保VARIABLE1[VARIABLE2]产生与使用iter(VARIABLE1)时相同的结果。这不可能自动完成。
如果您想学习如何编写2to3修复程序,请参考Lennart Regebro的书。

哇,伙计,全是大写字母是怎么回事?看起来有点疯狂哈哈 - jackcogdill
3
希望您能明白使用大写字母的含义:它们是占位符,其余部分是具体语法。 - Martin v. Löwis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接