Automatically simplifying/refactoring Python code (e.g. for loops - list comprehension)? [closed]

2024/9/19 9:09:43

In Python, I really enjoy how concise an implementation can be when using list comprehension. I love to do concise list comprehensions this:

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

However, I often encounter more verbose implementations like this:

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

When a for loop only looks through one data structure (e.g. myList[]), there is usually a straightforward list comprehension statement that is equivalent to the loop.
With this in mind, is there a refactoring tool that converts verbose Python loops into concise list comprehension statements?


Previous StackOverflow questions have asked for advice on transforming loops into list comprehension. But, I have yet to find a question about automatically converting loops into list comprehension expressions.


Motivation: There are numerous ways to answer the question "what does it mean for code to be clean?" Personally, I find that making code concise and getting rid of some of the fluff tends to make code cleaner and more readable. Naturally there's a line in the sand between "concise code" and "incomprehensible one-liners." Still, I often find it satisfying to write and work with concise code.

Answer

2to3 is a refactoring tool that can perform arbitrary refactorings, as long as you can specify them with a syntactical pattern. The pattern you might want to look for is this

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

This can be refactored safely to

VARIABLE1 = [EXPRESSION3 for VARIABLE2 in EXPRESSION1 if EXPRESSION2]

In your specific example, this would give

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

Then, you can have another refactoring that replaces xrange(0, N) with xrange(N), and another one that replaces

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

with

[VARIABLE3 for VARIABLE3 in VARIABLE1 if EXPRESSION1PRIME]

There are several problems with this refactoring:

  • EXPRESSION1PRIME must be EXPRESSION1 with all occurrences of VARIABLE1[VARIABLE2] replaced by VARIABLE3. This is possible with 2to3, but requires explicit code to do the traversal and replacement.
  • EXPRESSION1PRIME then must not contain no further occurrences of VARIABLE1. This can also be checked with explicit code.
  • One needs to come up with a name for VARIABLE3. You have chosen x; there is no reasonable way to have this done automatically. You could chose to recycle VARIABLE1 (i.e. i) for that, but that may be confusing as it suggests that i is still an index. It might work to pick a synthetic name, such as VARIABLE1_VARIABLE2 (i.e. myList_i), and check whether that's not used otherwise.
  • One needs to be sure that VARIABLE1[VARIABLE2] yields the same as you get when using iter(VARIABLE1). It's not possible to do this automatically.

If you want to learn how to write 2to3 fixers, take a look at Lennart Regebro's book.

https://en.xdnf.cn/q/72225.html

Related Q&A

Knowing the number of iterations needed for convergence in SVR scikit-learn

I am trying to optimize an SVR model and facing a problem because of overfitting, to overcome this I have tried to decrease the number of iterations instead of leaving it until convergence.To compare …

Why is `NaN` considered smaller than `-np.inf` in numpy?

What is the reason that NaNs are considered less than -np.inf in any comparisons involving np.min or np.argmin?import numpy as np In [73]: m = np.array([np.nan, 1., 0., -np.inf]) In [74]: n = np.array…

recursion within a class

I am trying to place a recursive formula inside a class statementclass SomeNode:def __init__(self, a):leng = len(a)half= leng/2self.firstnode=a[0][0]self.child1=SomeNode([a[i]for k in range(leng)])self…

There is an example of Spyne client?

Im trying to use spyne (http://spyne.io) in my server with ZeroMQ and MsgPack. Ive followed the examples to program the server side, but i cant find any example that helps me to know how to program the…

Safely bind method from one class to another class in Python [duplicate]

This question already has answers here:What is the difference between a function, an unbound method and a bound method?(6 answers)Closed 5 years ago.I know I can attach a function to a class and make …

Basic Python OpenCV cropping and resizing

can someone help me with a little cropping algorithm? its openCV.. im trying to figure this out. I know the method is crop = image[y:y1, x:x1]. If I have an image with new_dimensionXxnew_dimensionY pi…

Why does Keras loss drop dramatically after the first epoch?

Im training a U-Net CNN in Keras/Tensorflow and find that loss massively decreases between the last batch of the first epoch, and the first batch of the second epoch: Epoch 00001: loss improved from in…

extract strings from a binary file in python

I have a project where I am given a file and i need to extract the strings from the file. Basically think of the "strings" command in linux but im doing this in python. The next condition is …

Installing numpy on Mac to work on AWS Lambda

Is there a way to install numpy on a Mac so that it will work when uploaded to AWS Lambda? I have tried a variety of different ways, including using different pip versions, using easy_install, and fol…

python- how to get the output of the function used in Timer

I want to run a function for 10s then do other stuff. This is my code using Timerfrom threading import Timer import timedef timeout():b=truereturn ba=false t = Timer(10,timeout) t.start()while(a==f…