Как перечислить диапазон чисел, начинающийся с 1

154

Я использую 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?

Спасибо,

Джефф

JeffTaggary
источник
4
Просто любопытно, потому что я тот, кто не сделал много на пути Python профессионально. Вы ограничены Python 2.5, потому что ваша компания не хочет производить обновление по причинам совместимости?
Шон
2
Все версии 2.x обратно совместимы, так что это не причина.
Йохен Ритцель
Расскажите об этом некоторым модулям - есть некоторые, которые работают в Py 2.5, но не Py 2.6
xorsyst

Ответы:

179

Как вы уже упоминали, это легко сделать в 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 .

Марк Байерс
источник
использую izipи xrangeбуду ближе перечислять
Джон Ла Рой
7
Этот ответ устарел, теперь вы можете использовать только enumerate(iterable, start=1)Python 2.6.
Фредрик Бреннан
@frb: ты читал вопрос? Он уже знает решение для Python 2.6. Он специально попросил решение, которое работает в Python 2.5.
Марк Байерс
1
@MarkByers Видимо, я слепой :) Очень сожалею об этом. (Это № 1 в Google для "перечислять, начиная с 1")
Фредрик Бреннан
2
@ 8chan Да, я только что пришел сюда из поиска в Google "действительно ли перечислить начало с нулевого питона" :)
baxx
166

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

enumerate(sequence, start=1)

dhackner
источник
26
Обратите внимание, что это не пропускает первый элемент в списке, он смещает индекс по начальному значению, поэтому вы получите массив вне границ, если вы сделаете что-то вроде: sequence[i]в своем коде.
phyatt
14

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

def enum(seq, start=0):
    for i, x in enumerate(seq):
        yield i+start, x
Дункан
источник
12

Python 3

Официальная документация: enumerate(iterable, start=0)

Так что вы бы использовали это так:

>>> 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')]
winklerrr
источник
10

Простейший способ сделать в 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
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))работает.

Йохен Ритцель
источник
6

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

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

Обратите внимание, что это не нарушает код, используя перечисление без начального аргумента. Кроме того, этот oneliner может быть более элегантным и, возможно, более быстрым, но нарушает другое использование перечисления:

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

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


источник
Да, полная ерунда. Что-то в этом роде на самом деле сработало бы, например, в Haskell (каррирование - самая естественная вещь на этом языке, и из-за своей лени функция, берущая список, очень похожа на выражение-выражение генератора g). Но это не извиняет меня - давнего пользователя Python - пишущего BS. Спасибо за указание на это.
5
>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]
JAB
источник
перечислять должен быть генератор. создание целого списка за раз, чтобы перебрать, если часто не приемлемо
Джон Ла Рой
Обобщенный: список start = 4 (перечисление (диапазон (начало) + диапазон (1999, 2005))) [start:]
Тони Вейжалайнен
диапазон однако список в 2.52
Тони Вейжалайнен
3

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

Крис Б.
источник
1
Он не может сделать это в Python 2.5. Параметр start был представлен в Python 2.6: docs.python.org/library/functions.html#enumerate . Он также упоминает об этом в вопросе.
Марк Байерс
Ответили об этом до первоначального редактирования, когда код был не отформатирован, и проблема казалась мне использованием генератора вместо списка.
Крис Б.
++: это способ сделать это
Нас Банов
2

Хорошо, я чувствую себя немного глупо здесь ... в чем причина, чтобы просто не делать это с чем-то вроде
[(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
>>> 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))
Эли Кортрайт
источник
2
перечислять должен быть генератор. создание целого списка за раз, чтобы перебрать, если часто не приемлемо
Джон Ла Рой
0

Я не знаю, как эти посты можно сделать более сложными, чем следующие:

# Just pass the start argument to enumerate ...
for i,word in enumerate(allWords, 1):
    word2idx[word]=i
    idx2word[i]=word
BMC
источник