Как перечислить диапазон чисел начиная с 1 - PullRequest
120 голосов
/ 22 июля 2010

Я использую Python 2.5, я хочу перечисление, например, так (начиная с 1 вместо 0):

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

Я знаю, что в Python 2.6 вы можете сделать: h = enumerate (range (2000, 2005), 1), чтобы получить вышеуказанный результат, но в python2.5 вы не можете ...

Использование python2.5:

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

Кто-нибудь знает способ получить желаемый результат в Python 2.5?

Спасибо

Джеф

Ответы [ 12 ]

149 голосов
/ 06 февраля 2013

Просто чтобы поставить это здесь для потомков, в 2.6 был добавлен параметр "start" для перечисления следующим образом:

enumerate(sequence, start=1)

141 голосов
/ 22 июля 2010

Как вы уже упоминали, это легко сделать в Python 2.6 или новее:

enumerate(range(2000, 2005), 1)

Python 2.5 и старше не поддерживают параметр start, поэтому вместо этого вы можете создать два объекта диапазона и сжать их:

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

Результат:

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

Если вы хотите создать генератор вместо списка, вы можете использовать izip .

13 голосов
/ 22 июля 2010

Легко, просто определите свою собственную функцию, которая делает то, что вы хотите:

def enum(seq, start=0):
    for i, x in enumerate(seq):
        yield i+start, x
10 голосов
/ 22 июля 2010

Самый простой способ сделать в Python 2.5 именно то, о чем вы спрашиваете:

import itertools as it

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

Если вы хотите получить список, как вам кажется, используйте zip вместо it.izip.

(Кстати, как правило, лучший способ сделать список из генератора или любого другого итеративного X - это не [x for x in X], а скорее list(X)).

6 голосов
/ 22 июля 2010
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

Сейчас h = list(enumerate(xrange(2000, 2005), 1)) работает.

5 голосов
/ 22 июля 2010

перечисление является тривиальным, и поэтому повторно реализует его, чтобы принять начало:

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

Обратите внимание, что это не нарушает код, используя перечисление без начального аргумента. В качестве альтернативы этот oneliner может быть более элегантным и, возможно, более быстрым, но нарушает другие варианты использования перечисления: enumerate = ((index+1, item) for index, item)

Последнее было чистой ерундой. @ Дункан правильно понял.

4 голосов
/ 22 июля 2010
>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]
3 голосов
/ 22 июля 2010

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

2 голосов
/ 22 июля 2010

Хорошо, я чувствую себя немного глупо ... в чем причина не просто делать это с чем-то вроде[(a+1,b) for (a,b) in enumerate(r)]?Если вы не будете работать, не проблема:

>>> 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)]
1 голос
/ 22 июля 2010
>>> h = enumerate(range(2000, 2005))
>>> [(tup[0]+1, tup[1]) for tup in h]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

Поскольку это несколько многословно, я бы порекомендовал написать собственную функцию для ее обобщения:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...