Idiomatic Python: 'times' loop

Question:

Say I have a function `foo` that I want to call `n` times. In Ruby, I would write:

``````n.times { foo }
``````

In Python, I could write:

``````for _ in xrange(n): foo()
``````

But that seems like a hacky way of doing things.

My question: Is there an idiomatic way of doing this in Python?

You’ve already shown the idiomatic way:

``````for _ in range(n): # or xrange if you are on 2.X
foo()
``````

Not sure what is “hackish” about this. If you have a more specific use case in mind, please provide more details, and there might be something better suited to what you are doing.

Fastest, cleanest is itertools.repeat:

``````import itertools

for _ in itertools.repeat(None, n):
foo()
``````

The question pre-supposes that calling foo() n times is an a priori necessary thing. Where did n come from? Is it the length of something iterable? Then iterate over the iterable. As I am picking up Python, I find that I’m using few to no arbitrary values; there is some more salient meaning behind your n that got lost when it became an integer.

Earlier today I happened upon Nicklaus Wirth’s provocative paper for IEEE Computer entitled Good Ideas – Through the Looking Glass (archived version for future readers). In section 4 he brings a different slant on programming constructs that everyone (including himself) has taken for granted but that hold expressive flaws:

“The generality of Algolâ€™s `for`
statement should have been a warning
signal to all future designers to
always keep the primary purpose of a
construct in mind, and to be weary of
exaggerated generality and complexity,
which may easily become
counter-productive.”

The algol `for` is equivalent to the C/Java `for`, it just does too much. That paper is a useful read if only because it makes one not take for granted so much that we so readily do. So perhaps a better question is “Why would you need a loop that executes an arbitrary number of times?”

If you want the `times` method, and you need to use it on your own functions, try this:

``````def times(self, n, *args, **kwargs):
for _ in range(n):
self.__call__(*args, **kwargs)

import new
def repeatable(func):
func.times = new.instancemethod(times, func, func.__class__)
return func
``````

now add a `@repeatable` decorator to any method you need a `times` method on:

``````@repeatable
def foo(bar):
print bar

foo.times(4, "baz") #outputs 4 lines of "baz"
``````
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.