On Fri, 16 Feb 2007 07:30:15 -0800, stdazi wrote: > Hello! > > Many times I was suggested to use xrange and range instead of the > while constructs, and indeed, they are quite more elegant - but, after > calculating the overhead (and losen flexibility) when working with > range/xrange, and while loops, you get to the conclusion that it isn't > really worth using range/xrange loops.
I prefer to _measure_ the overhead instead of guessing. import timeit whileloop = """i = 0 while i < N: i += 1 pass """ forloop = """for i in xrange(N): pass """ Now let's see how fast the loops are. >>> timeit.Timer(whileloop, "N = 10000").repeat(3, 1000) [3.5716907978057861, 3.5263650417327881, 3.5975079536437988] >>> timeit.Timer(forloop, "N = 10000").repeat(3, 1000) [1.3608510494232178, 1.341961145401001, 1.3180010318756104] Looks to me that a for loop using xrange is more than twice as fast as a while loop. The advantage is about the same for small N: >>> timeit.Timer(whileloop, "N = 100").repeat(3, 1000) [0.052264213562011719, 0.049374103546142578, 0.041945934295654297] >>> timeit.Timer(forloop, "N = 100").repeat(3, 1000) [0.012259006500244141, 0.013512134552001953, 0.015196800231933594] What makes you think that a while loop has less overhead? > I'd like to show some examples and I'll be glad if someone can suggest > some other fixes than while a loop :-) > > a) range overfllow : > > > for i in range(0, 1 << len(S)) : > ..... > OverflowError: range() result has too many items > > ok, so we fix this one with xrange ! By the way, you don't need to write range(0, N). You can just write range(N). Yes, you're correct, range(some_enormous_number) will fail if some_enormous_number is too big. > b) xrange long int overflow : > > for i in xrange(0, 1 << len(S)) : > ........ > OverflowError: long int too large to convert to int Are you really doing something at least 2147483647 times? I'm guessing that you would be better off rethinking your algorithm. > Next thing I miss is the flexibility as in C for loops : > > for (i = 0; some_function() /* or other condition */ ; i++) This would be written in Python as: i = 0 while some_function(): i += 1 A more flexible way would be to re-write some_function() as an iterator, then use it directly: for item in some_function(): # do something with item > or, > > for (i = 0 ; i < 10 ; i++) > i = 10; This would be written in Python as: for i in xrange(10): i = 10 > I don't think range/xrange sucks, but I really think there should be > some other constructs to improve the looping flexibility. Every loop can be turned into a while loop. If you have while, you don't _need_ anything else. But for elegance and ease of use, a small number of looping constructs is good. Python has: while condition: block else: # runs if while exits *without* hitting break statement block for item in any_sequence: block else: # runs if for exits *without* hitting break statement block Nice, clean syntax. any_sequence isn't limited to mere arithmetic sequences -- it can be any sequence of any objects. But if you need a C-style for loop, using integers, range/xrange([start, ] stop [, step]) is provided. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list