Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Python have any for loop equivalent (not foreach)

Python's iterators are great and all, but sometimes I really do want a C-style for loop - not a foreach loop. For example, I have a start date and an end date and I want to do something for every day in that range. I can do this with a while loop, of course:

    current = start
    while current <= finish:
        do_stuff(current)
        current += timedelta(1)

This works, but it's 3 lines instead of 1 (in C or C-based languages) and I often find myself forgetting to write the incrementing line, especially if the loop body is quite complex. Is there a more elegant and less error-prone way of doing this in Python?

like image 736
EMP Avatar asked Dec 23 '09 00:12

EMP


1 Answers

The elegant and Pythonic way to do it is to encapsulate the idea of a range of dates in its own generator, then use that generator in your code:

import datetime

def daterange(start, end, delta):
    """ Just like `range`, but for dates! """
    current = start
    while current < end:
        yield current
        current += delta

start = datetime.datetime.now()
end = start + datetime.timedelta(days=20)

for d in daterange(start, end, datetime.timedelta(days=1)):
    print d

prints:

2009-12-22 20:12:41.245000
2009-12-23 20:12:41.245000
2009-12-24 20:12:41.245000
2009-12-25 20:12:41.245000
2009-12-26 20:12:41.245000
2009-12-27 20:12:41.245000
2009-12-28 20:12:41.245000
2009-12-29 20:12:41.245000
2009-12-30 20:12:41.245000
2009-12-31 20:12:41.245000
2010-01-01 20:12:41.245000
2010-01-02 20:12:41.245000
2010-01-03 20:12:41.245000
2010-01-04 20:12:41.245000
2010-01-05 20:12:41.245000
2010-01-06 20:12:41.245000
2010-01-07 20:12:41.245000
2010-01-08 20:12:41.245000
2010-01-09 20:12:41.245000
2010-01-10 20:12:41.245000

This is similar to the answer about range, except that the built-in range won't work with datetimes, so we have to create our own, but at least we can do it just once in an encapsulated way.

like image 164
Ned Batchelder Avatar answered Sep 28 '22 00:09

Ned Batchelder