Pythonic way to write a for loop that doesn't use the loop index [duplicate]
This is to do with the following code, which uses a for loop to generate a series of random offsets for use elsewhere in the program.
The index of this for loop is unused, and this is resulting in the 'offending' code being highlighted as a warning by Eclipse / PyDev
def RandomSample(count):
pattern = []
for i in range(count):
pattern.append( (random() - 0.5, random() - 0.5) )
return pattern
So I either need a better way to write this loop that doesn't need a loop index, or a way to tell PyDev to ignore this particular instance of an unused variable.
Does anyone have any suggestions?
Just for reference for ignoring variables in PyDev
By default pydev will ignore following variables
['_', 'empty', 'unused', 'dummy']
You can add more by passing supression parameters
-E, --unusednames ignore unused locals/arguments if name is one of these values
Ref: http://eclipse-pydev.sourcearchive.com/documentation/1.0.3/PyCheckerLauncher_8java-source.html
How about itertools.repeat:
import itertools
count = 5
def make_pat():
return (random() - 0.5, random() - 0.5)
list(x() for x in itertools.repeat(make_pat, count))
Sample output:
[(-0.056940506273799985, 0.27886450895662607),
(-0.48772848046066863, 0.24359038079935535),
(0.1523758626306998, 0.34423337290256517),
(-0.018504578280469697, 0.33002406492294756),
(0.052096928160727196, -0.49089780124549254)]
randomSample = [(random() - 0.5, random() - 0.5) for _ in range(count)]
Sample output, for count=10
and assuming that you mean the Standard Library random()
function:
[(-0.07, -0.40), (0.39, 0.18), (0.13, 0.29), (-0.11, -0.15),\
(-0.49, 0.42), (-0.20, 0.21), (-0.44, 0.36), (0.22, -0.08),\
(0.21, 0.31), (0.33, 0.02)]
If you really need to make it a function, then you can abbreviate by using a lambda
:
f = lambda count: [(random() - 0.5, random() - 0.5) for _ in range(count)]
This way you can call it like:
>>> f(1)
f(1)
[(0.03, -0.09)]
>>> f(2)
f(2)
[(-0.13, 0.38), (0.10, -0.04)]
>>> f(5)
f(5)
[(-0.38, -0.14), (0.31, -0.16), (-0.34, -0.46), (-0.45, 0.28), (-0.01, -0.18)]
>>> f(10)
f(10)
[(0.01, -0.24), (0.39, -0.11), (-0.06, 0.09), (0.42, -0.26), (0.24, -0.44) , (-0.29, -0.30), (-0.27, 0.45), (0.10, -0.41), (0.36, -0.07), (0.00, -0.42)]
>>>
you get the idea...
Late to the party, but here's a potential idea:
def RandomSample(count):
f = lambda: random() - 0.5
r = range if count < 100 else xrange # or some other number
return [(f(), f()) for _ in r(count)]
Strictly speaking, this is more or less the same as the other answers, but it does two things that look kind of nice to me.
First, it removes that duplicate code you have from writing random() - 0.5
twice by putting that into a lambda.
Second, for a certain size range, it chooses to use xrange()
instead of range()
so as not to unnecessarily generate a giant list of numbers you're going to throw away. You may want to adjust the exact number, because I haven't played with it at all, I just thought it might be a potential efficiency concern.
There should be a way to suppress code analysis errors in PyDev, like this:
http://pydev.org/manual_adv_assistants.html
Also, PyDev will ignore unused variables that begin with an underscore, as shown here:
http://pydev.org/manual_adv_code_analysis.html
Try this:
while count > 0:
pattern.append((random() - 0.5, random() - 0.5))
count -= 1
import itertools, random
def RandomSample2D(npoints, get_random=lambda: random.uniform(-.5, .5)):
return ((r(), r()) for r in itertools.repeat(get_random, npoints))
- uses
random.uniform()
explicitly - returns an iterator instead of list
精彩评论