views:

227

answers:

11

I have some code of the form:

for i in range(nIterations):
    y = f(y)

Where f is a function defined elsewhere. hopefully the idea of that code is that after it's run y will have had f applied to it nIterations times.

Is there a way in python to write this in a single line?

+5  A: 

like this?

for i in range(nIterations): y = f(y)

A for loop with one command can be written as a single line.

EDIT

Or maybe slightly cleaner:

for _ in xrange(nIterations): y = f(y)

Since you don't want to have a something that can be split into two separate statements (i think), here's another one:

reduce(lambda y, _: f(y), xrange(nIterations), initValue)

Still, I would recommend to just use your original code, which is much more intuitive and readable. Also note what Guido van Rossum has to say on loops versus repeat. Note by the way that (in python 2.x) xrange is more efficient than range for large nIterations as it returns an actual iterator and not an allocated list.

catchmeifyoutry
+1 - I think that there is a pythonesque way to do what the OP wants though.
KevinDTimm
haha. No. All you've done is removed the return, in my mind it's still "there", and two separate lines. I'm just doing this as an exercise in ridiculousness, haha, and wondering if there's a way that it could be done.
VolatileStorm
Yes, I've only removed your return. Now it's a single line. What more do you want ;)
catchmeifyoutry
Wasn't python set to lose the `reduce` function? Or am I wholly behind the times here?
Daniel May
@Daniel May, reduce is still available in Python3, but has been moved to the functools module. See http://diveintopython3.org/porting-code-to-python-3-with-2to3.html#reduce
unutbu
Thanks, this is what I was looking for. I pretty much understand how that's gonna work apart from the definition of the lambda function.lambda y, _: f(y)Why is there the ", _"? What purpose does that serve?
VolatileStorm
Ah! Thanks for that!
Daniel May
The `_` is just a placeholder for a temporary variable you won't use later. If you read this code, it's immediately clear you're not really interested in that variable, but you need to include it anyway to make the code work.
catchmeifyoutry
+2  A: 

So like this you mean?

for i in range(nIterations): y = f(y)

While this might seem nice and pretty, I'd argue (as has been done in the comments below your post) that this doesn't improve readability, and is best off left as 2 lines.

Dominic Bou-Samra
A: 

Just stick it all on one line like this: for i in range(nIterations): y = f(y)

The decision to have code on one line or multiple has been an argument for years - there is no performance increase - just lay it out how you like it and how you can read it best.

Daniel May
A: 

Your question lacks context, but this could be rewritten using map function or list comprehension (both one-liners)

gorsky
how could it be rewritten using list comprehensions? That's kinda what I'm looking for.
VolatileStorm
that's wrong, re-read the question.
SilentGhost
It could be rewritten with `reduce`, but not with `map` or a list comprehension.
sth
You're right, guys - missed the point. I'd better read it more accurately.
gorsky
A: 

Not exactly one line, but once you define the power operation for functions:

def f_pow(f, n):
  if n == 1:
    return f
  else:
    return lambda x: f_pow(f, n-1)(f(x))

you can write this:

f_pow(f, nIterations)(y)
Wim
A: 

reduce(lambda y,_: f(y),xrange(niterations),y)

unutbu
A: 

Ok this is probably a very weird an incomprehensible use of the reduce function, so for real code I'd stick with what you have. But just for the fun of it, here goes:

reduce(lambda a, b: f(a), range(nIterations), y)
Wim
A: 

If you make y mutable, then you can use list comprehension. But this isn't something I'd use in real code, unless really necessary.

def f(y):
    y[0] += 5

y = [0]
[f(y) for _ in xrange(10)]
print y[0] # => 50
PiotrLegnica
A: 

While I'd suggest you keep the original code snippet as it is much clearer, you can accomplish this with a single line of code using the reduce function:

reduce(lambda a,b: f(a), xrange(nIterations), y)
Mark Roddy
A: 

You can create such snippets using semicolons ; if you need to execute more than one instruction inside the loop, here is an example:

for i in xrange(nIterations): x=f(i); y=f(x); z=f(y)
Andrea Ambu
A: 

y=[f(y) for i in range(niteration)]

hope that helps ;)

Ahmad Dwaik
that's wrong, re-read the question
SilentGhost