如何枚举从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中获得理想结果的方法?

谢谢,

杰夫


4
只是好奇,因为我是一个在Python方面没有做太多事情的人。您是否限于Python 2.5,因为您的公司出于兼容性原因而不想进行升级?
肖恩(Sean)2010年

2
所有2.x版本都是向后兼容的,因此没有理由。
Jochen Ritzel 2010年

告诉一些模块-有一些可以在Py 2.5中工作,但不能在Py 2.6中工作
xorsyst

Answers:


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将更接近枚举
John La Rooy 2010年

7
这个答案已经过时了,您现在可以将enumerate(iterable, start=1)其与Python 2.6一样。
Fredrick Brennan

@frb:您阅读问题了吗?他已经知道Python 2.6的解决方案。他特别要求提供一种可在Python 2.5中使用的解决方案。
Mark Byers

1
@MarkByers显然我是盲目的:)对此感到非常抱歉。(这是Google中“枚举从1开始”的第一名)
Fredrick Brennan

2
@ 8chan是的,我刚从Google搜索到“确实从零python开始枚举” :)
baxx

166

只是为了后代而已,在2.6中添加了“ start”参数来进行枚举,如下所示:

enumerate(sequence, start=1)


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')]

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中工作(在该语言中,currying是最自然的事情,并且由于其惰性,带有列表的函数与生成器表达式非常相似)。但这并不能为我-长期使用python的用户-编写BS辩解。感谢您指出。

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

枚举应该是一个生成器。一次创建一个完整的列表,只是经常进行迭代(如果通常不被接受)
John La Rooy,2010年

广义:start = 4 list(enumerate(range(start)+ range(1999,2005)))[start:]
Tony Veijalainen 2010年

但是范围在2.52中列出
Tony Veijalainen 2010年


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
枚举应该是一个生成器。一次创建一个完整的列表,只是经常进行迭代(如果常常不被接受)
John La Rooy 2010年

0

我不知道这些帖子如何变得比以下内容更复杂:

# Just pass the start argument to enumerate ...
for i,word in enumerate(allWords, 1):
    word2idx[word]=i
    idx2word[i]=word
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.