Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python enumerate downwards or with a custom step

Tags:

How to make Python's enumerate function to enumerate from bigger numbers to lesser (descending order, decrement, count down)? Or in general, how to use different step increment/decrement in enumerate?

For example, such function, applied to list ['a', 'b', 'c'], with start value 10 and step -2, would produce iterator [(10, 'a'), (8, 'b'), (6, 'c')].

like image 311
Mirzhan Irkegulov Avatar asked Jun 18 '14 15:06

Mirzhan Irkegulov


People also ask

What does enumerate () do in Python?

Python enumerate() Function The enumerate() function takes a collection (e.g. a tuple) and returns it as an enumerate object. The enumerate() function adds a counter as the key of the enumerate object.

Is enumerate faster than for loop?

Using enumerate() is more beautiful but not faster for looping over a collection and indices.

Is enumerate or range faster?

enumerate() is faster when you want to repeatedly access the list/iterable items at their index. When you just want a list of indices, it is faster to use len() and range().

Does enumerate work with lists?

The enumerate() function takes in an iterable as an argument, such as a list, string, tuple, or dictionary. In addition, it can also take in an optional argument, start, which specifies the number we want the count to start at (the default is 0). And that's it!


2 Answers

I haven't found more elegant, idiomatic, and concise way, than to write a simple generator:

def enumerate2(xs, start=0, step=1):     for x in xs:         yield (start, x)         start += step 

Examples:

>>> list(enumerate2([1,2,3], 5, -1)) [(5, 1), (4, 2), (3, 3)] >>> list(enumerate2([1,2,3], 5, -2)) [(5, 1), (3, 2), (1, 3)] 

If you don't understand the above code, read What does the "yield" keyword do in Python? and Difference between Python's Generators and Iterators.

like image 179
Mirzhan Irkegulov Avatar answered Sep 30 '22 21:09

Mirzhan Irkegulov


One option is to zip your iterable to a range:

for index, item in zip(range(10, 0, -2), ['a', 'b', 'c']):     ... 

This does have the limitation that you need to know how far the range should go (the minimum it should cover - as in my example, excess will be truncated by zip).

If you don't know, you could roll your own "infinite range" and use that:

>>> def inf_range(start, step):     """Generator function to provide a never-ending range."""     while True:         yield start         start += step   >>> list(zip(inf_range(10, -2), ['a', 'b', 'c'])) [(10, 'a'), (8, 'b'), (6, 'c')] 
like image 36
jonrsharpe Avatar answered Sep 30 '22 20:09

jonrsharpe