What's the best Python idiom for this C construct?
while ((x = next()) != END) {
....
}
I don't have the ability to recode next().
update: and the answer from seems to be:
for x in iter(next, END):
....
What's the best Python idiom for this C construct?
while ((x = next()) != END) {
....
}
I don't have the ability to recode next().
update: and the answer from seems to be:
for x in iter(next, END):
....
Maybe it's not terribly idiomatic, but I'd be inclined to go with
x = next()
while x != END:
do_something_with_x
x = next()
... but that's because I find that sort of thing easy to read
What are you trying to do here?
If you're iterating over a list, you can use for e in L
where e is the element and L is the list. If you're filtering a list, you can use list comprehensions (i.e. [ e for e in L if e % 2 == 0 ]
to get all the even numbers in a list).
It depends a bit what you want to do. To match your example as far as possible, I would make next a generator and iterate over it:
def next():
for num in range(10):
yield num
for x in next():
print x
If you need to do this more than once, the pythonic way would use an iterator
for x in iternext():
do_something_with_x
where iternext
would be defined using something like
(explicit is better than implicit!):
def iternext():
x = next()
while x != END:
yield x
x = next()
Short answer: there's no way to do inline variable assignment in a while loop in Python. Meaning that I cannot say:
while x=next():
// do something here!
Since that's not possible, there are a number of "idiomatically correct" ways of doing this:
while 1:
x = next()
if x != END:
// Blah
else:
break
Obviously, this is kind of ugly. You can also use one of the "iterator" approaches listed above, but, again, that may not be ideal. Finally, you can use the "pita pocket" approach that I actually just found while googling:
class Pita( object ):
__slots__ = ('pocket',)
marker = object()
def __init__(self, v=marker):
if v is not self.marker:
self.pocket = v
def __call__(self, v=marker):
if v is not self.marker:
self.pocket = v
return self.pocket
Now you can do:
p = Pita()
while p( next() ) != END:
// do stuff with p.pocket!
Thanks for this question; learning about the __call__
idiom was really cool! :)
EDIT: I'd like to give credit where credit is due. The 'pita pocket' idiom was found here
Can you provide more information about what you're trying to accomplish? It's not clear to me why you can't just say
for x in everything():
...
and have the everything function return everything, instead of writing a next function to just return one thing at a time. Generators can even do this quite efficiently.
@Mark Harrison's answer:
for x in iter(next_, END):
....
Here's an excerpt from Python's documentation:
iter(o[, sentinel])
Return an iterator object. ...(snip)... If the second argument,
sentinel
, is given, theno
must be a callable object. The iterator created in this case will callo
with no arguments for each call to itsnext()
method; if the value returned is equal tosentinel
,StopIteration
will be raised, otherwise the value will be returned.