Simulating C-style for loops in python

后端 未结 6 1429
孤独总比滥情好
孤独总比滥情好 2020-12-13 05:05

(even the title of this is going to cause flames, I realize)

Python made the deliberate design choice to have the for loop use explicit iterables, with

相关标签:
6条回答
  • 2020-12-13 05:30

    This is the best I can come up with:

    def cfor(first,test,update):
        while test(first):
            yield first
            first = update(first)
    
    def example(blah):
        print "do some stuff"
        for i in cfor(0,lambda i:i<blah,lambda i:i+1):
            print i
        print "done"
    

    I wish python had a syntax for closured expressions.

    Edit: Also, note that you only have to define cfor once (as opposed to your complicated_iterator function).

    0 讨论(0)
  • 2020-12-13 05:33

    I'm a little confused: you have a complicated while expression, and a complicated next expression, but they fit nicely into a C for loop? That doesn't make sense to me.

    I recommend the custom iterator approach. You will likely find other uses for the iterator, and encapsulating the iteration is good practice anyway.

    UPDATE: Using your example, I would definitely make a custom iterator. It seems perfectly natural to me that a calendar would be able to generate a series of quarterly dates:

    class Calendar:
        # ...
    
        def quarters(self, start, end):
            """Generate the quarter-start dates between `start` and `end`."""
            date = start
            while date < end:
                yield date
                date = self.next_quarter_end(date)
    
    
    for date in calendar.quarters(start, end):
        if another_calendar.is_holiday(date):
           continue
        # ... do stuff...
    

    This seems like a wonderful abstraction for your calendar class to provide, and I bet you'll use it more than once.

    0 讨论(0)
  • 2020-12-13 05:35

    I often do

    while True:
       val = <awkward/complicated update>
       if not val:
         break
    
       etc.
    
    0 讨论(0)
  • 2020-12-13 05:36

    What about:

    date = start
    
    while date < end:
    
        if not another_calendar.is_holiday(date):
            # ... do stuff...
    
        date = calendar.next_quarter_end(date)
    

    But if you use that particular construct often, you're better off defining the generator once and re-using it as you did in your question.

    (The fact is, since they're different languages, you can't possibly have every construct in C map to a more compact construct in Python. It's like claiming to have a compression algorithm that works equally well on all random inputs.)

    0 讨论(0)
  • 2020-12-13 05:38

    You could use a try/finally clause to execute the update:

    val = START_VAL
    
    while <awkward/complicated test case>:
        try:
            # do stuff
            continue
    
        finally:
            val = <awkward/complicated update>
    

    Caveat: this will also execute the update statement if you do a break.

    0 讨论(0)
  • 2020-12-13 05:39

    Heh:

    def forre(a,i,c,top,increment,run):
        increment = increment.replace("++","+=1").replace("--","-=1").replace("; ","")
        while i != top:
            try: exec(run)
            except: print "error: "; print run
            try: exec(increment)
            except: print "error: "; print increment
    
    forre("int i=",0,"; i<",6,"; i++", 
        "print i"
        )
    
    0 讨论(0)
提交回复
热议问题