How to enumerate a range of numbers starting at 1

I am using Python 2.5, I want an enumeration like so (starting at 1 instead of 0):

[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

I know in Python 2.6 you can do: h = enumerate(range(2000, 2005), 1) to give the above result but in python2.5 you cannot…

Using Python 2.5:

>>> h = enumerate(range(2000, 2005))
>>> [x for x in h]
[(0, 2000), (1, 2001), (2, 2002), (3, 2003), (4, 2004)]

Does anyone know a way to get that desired result in Python 2.5?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

As you already mentioned, this is straightforward to do in Python 2.6 or newer:

enumerate(range(2000, 2005), 1)

Python 2.5 and older do not support the start parameter so instead you could create two range objects and zip them:

r = xrange(2000, 2005)
r2 = xrange(1, len(r) + 1)
h = zip(r2, r)
print h

Result:

[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

If you want to create a generator instead of a list then you can use izip instead.

Method 2

Just to put this here for posterity sake, in 2.6 the “start” parameter was added to enumerate like so:

enumerate(sequence, start=1)

Method 3

Python 3

Official Python documentation: enumerate(iterable, start=0)

You don’t need to write your own generator as other answers here suggest. The built-in Python standard library already contains a function that does exactly what you want:

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

The built-in function is equivalent to this:

def enumerate(sequence, start=0):
  n = start
  for elem in sequence:
    yield n, elem
    n += 1

Method 4

Easy, just define your own function that does what you want:

def enum(seq, start=0):
    for i, x in enumerate(seq):
        yield i+start, x

Method 5

Simplest way to do in Python 2.5 exactly what you ask about:

import itertools as it

... it.izip(it.count(1), xrange(2000, 2005)) ...

If you want a list, as you appear to, use zip in lieu of it.izip.

(BTW, as a general rule, the best way to make a list out of a generator or any other iterable X is not [x for x in X], but rather list(X)).

Method 6

from itertools import count, izip

def enumerate(L, n=0):
    return izip( count(n), L)

# if 2.5 has no count
def count(n=0):
    while True:
        yield n
        n+=1

Now h = list(enumerate(xrange(2000, 2005), 1)) works.

Method 7

enumerate is trivial, and so is re-implementing it to accept a start:

def enumerate(iterable, start = 0):
    n = start
    for i in iterable:
        yield n, i
        n += 1

Note that this doesn’t break code using enumerate without start argument. Alternatively, this oneliner may be more elegant and possibly faster, but breaks other uses of enumerate:

enumerate = ((index+1, item) for index, item)

The latter was pure nonsense. @Duncan got the wrapper right.

Method 8

>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

Method 9

h = [(i + 1, x) for i, x in enumerate(xrange(2000, 2005))]

Method 10

Ok, I feel a bit stupid here… what’s the reason not to just do it with something like
[(a+1,b) for (a,b) in enumerate(r)] ? If you won’t function, no problem either:

>>> r = range(2000, 2005)
>>> [(a+1,b) for (a,b) in enumerate(r)]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

>>> enumerate1 = lambda r:((a+1,b) for (a,b) in enumerate(r)) 

>>> list(enumerate1(range(2000,2005)))   # note - generator just like original enumerate()
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

Method 11

>>> h = enumerate(range(2000, 2005))
>>> [(tup[0]+1, tup[1]) for tup in h]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

Since this is somewhat verbose, I’d recommend writing your own function to generalize it:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))

Method 12

I don’t know how these posts could possibly be made more complicated then the following:

# Just pass the start argument to enumerate ...
for i,word in enumerate(allWords, 1):
    word2idx[word]=i
    idx2word[i]=word


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x