Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most Pythonic way equivalent for: while ((x = next()) != END)

Tags:

python

c

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):
    ....
like image 553
Mark Harrison Avatar asked Aug 26 '08 16:08

Mark Harrison


3 Answers

@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, then o must be a callable object. The iterator created in this case will call o with no arguments for each call to its next() method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.

like image 88
jfs Avatar answered Oct 17 '22 15:10

jfs


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
like image 27
Johannes Hoff Avatar answered Oct 17 '22 15:10

Johannes Hoff


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

like image 4
FreeMemory Avatar answered Oct 17 '22 15:10

FreeMemory