Як перерахувати діапазон чисел, починаючи з 1


154

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

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

Я знаю, що в Python 2.6 ви можете зробити: h = перерахувати (діапазон (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?

Дякую,

Джефф


4
Цікаво, адже я хтось, хто не багато зробив на шляху Python професійно. Ви обмежені Python 2.5, оскільки ваша компанія не хоче робити оновлення з міркувань сумісності?
Шон

2
Всі версії 2.x назад сумісні, тому немає ніяких причин.
Jochen Ritzel

Скажіть, що для деяких модулів - є кілька таких, які працюють у 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 search "чи перераховує початок з нульового python" :)
baxx

166

Просто для того, щоб зробити це для нащадків, у 2.6 додано параметр "start" для перерахування так:

enumerate(sequence, start=1)


26
Зауважте, що це не пропускає перший елемент у списку, він зміщує індекс на початкове значення, тому ви отримаєте масив поза межами, якщо ви зробили щось подібне: sequence[i]у своєму коді.
фіат

14

Просто, просто визначте власну функцію, яка виконує те, що ви хочете:

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

12

Пітон 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')]

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

Зауважте, що це не порушує код за допомогою перерахування без аргументу початку. Крім того, цей онлайнер може бути більш елегантним і, можливо, швидшим, але порушує інші способи перерахування:

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

Останнє було чистою дурницею. @Duncan отримав обгортку правильно.


Так, тотальна нісенітниця. Щось у цих напрямках насправді спрацювало б, наприклад, у Haskell (currying - це найприродніша річ на цій мові, і через його лінь функція, що займає список, дуже схожа на генератор expressg). Але це не виправдає мене - давній користувач python - пише BS. Дякуємо, що вказали на це.

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

перерахувати має бути генератором. створення одразу всього списку просто для перегляду, якщо часто це не прийнятно
Джон Ла Руй

Узагальнено: start = 4 список (перерахувати (діапазон (старт) + діапазон (1999, 2005)))) [початок:]
Tony Veijalainen

Але список є в 2,52
Tony Veijalainen

3

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


1
Він не може цього зробити в Python 2.5. Параметр запуску введено в 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.