28

Could you please tell me why it is considered as "not pythonic" when I need the index and the value when looping over a list and use:

a = [1,2,3]
for i in range(len(a)):
  # i is the idx
  # a[i] is the value

but rather it is recommended to use

for idx, val in enumerate(a):
  print idx, val

who defines "pythonic" and why is the latter one better? I mean it's not that much better concerning readability, is it!?

Thanks in advance

  • 4
    Possible dupe of http://stackoverflow.com/questions/11901081/only-index-needed-enumerate-or-xrange – dano Jun 10 '14 at 21:05
  • 1
    *I mean it's not that much better concerning readability, is it!?* it actually is, because the first example uses an extra line of code – Tim Jun 10 '14 at 21:06
  • 3
    Voting to reopen. It does depend on opinions to some degree, but there are good reasons to prefer the second version, as shown in @ThiefMaster's answer. – juanchopanza Jun 11 '14 at 05:18
  • 1
    Thanks, nice to hear I did not really break the rules in my first post :-) –  Jun 11 '14 at 07:37

1 Answers1

30

First of all, the first way is ugly: You either need a separate variable assignment to get the element or use a[i] all the time which could theoretically be an expensive operation. Imagine a being a database cursor: When you iterate it (a.__iter__ being called) the object can safely assume that you are going to iterate over all its items. So all or at least multiple rows could be retrieved at once. When getting the length such an optimization would be stupid though since you surely don't want to retrieve data just because you want the number of items. Also, when retrieving a specific item you cannot assume that other items will be retrieved, too.

Additionally, using enumerate() works with any iterable while range(len()) only works with countable, indexable objects.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 7
    Thanks, especially your last paragraph is a very good reason for me because otherwise I'd always have to use different versions which would be counterproductive and irregular. I think it's better and cleaner to always use the same then :-) –  Jun 11 '14 at 07:38
  • 4
    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 to use len() and range (xrange in Python 2.x). – ofer.sheffer Nov 20 '16 at 17:35