Cómo enumerar un rango de números que comienzan en 1

154

Estoy usando Python 2.5, quiero una enumeración como esta (comenzando en 1 en lugar de 0):

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

Sé que en Python 2.6 puedes hacer: h = enumerate (range (2000, 2005), 1) para dar el resultado anterior, pero en python2.5 no puedes ...

Usando python2.5:

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

¿Alguien sabe una manera de obtener ese resultado deseado en Python 2.5?

Gracias,

Jeff

JeffTaggary
fuente
44
Es curioso, ya que soy alguien que no ha hecho mucho en el camino de Python profesionalmente. ¿Está limitado a Python 2.5 porque su empresa no desea realizar la actualización por razones de compatibilidad?
Sean
2
Todas las versiones 2.x son compatibles con versiones anteriores, por lo que no hay razón.
Jochen Ritzel
Dígalo a algunos módulos: hay algunos que funcionan en Py 2.5 pero no en Py 2.6
xorsyst

Respuestas:

179

Como ya mencionó, esto es sencillo de hacer en Python 2.6 o posterior:

enumerate(range(2000, 2005), 1)

Python 2.5 y versiones anteriores no admiten el startparámetro, por lo que podría crear dos objetos de rango y comprimirlos:

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

Resultado:

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

Si desea crear un generador en lugar de una lista, puede usar izip en su lugar.

Mark Byers
fuente
usando izipy xrangeestaría más cerca de enumerar
John La Rooy
77
Esta respuesta está desactualizada, ahora puede ponerla a enumerate(iterable, start=1)partir de Python 2.6.
Fredrick Brennan
@frb: ¿Leíste la pregunta? Él ya conoce la solución para Python 2.6. Solicitó específicamente una solución que funcione en Python 2.5.
Mark Byers
1
@MarkByers Aparentemente estoy ciego :) Realmente lo siento por eso. (Este es el número 1 en Google para "enumerar a partir de 1")
Fredrick Brennan
2
@ 8chan sí, acabo de llegar de Google buscando "enumera el inicio desde cero python" :)
baxx
166

Solo para poner esto aquí por el bien de la posteridad, en 2.6 se agregó el parámetro "inicio" para enumerar así:

enumerate(sequence, start=1)

dhackner
fuente
26
Tenga en cuenta que esto no omite el primer elemento de la lista, compensa el índice por el valor inicial, por lo que obtendría una matriz fuera de los límites si hiciera algo como: sequence[i]en su código.
phyatt
14

Fácil, solo defina su propia función que haga lo que quiera:

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

Python 3

Documentación oficial: enumerate(iterable, start=0)

Entonces lo usarías así:

>>> 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
fuente
10

La forma más simple de hacer en Python 2.5 exactamente lo que preguntas:

import itertools as it

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

Si desea una lista, como parece, úsela zipen lugar de it.izip.

(Por cierto, como regla general, la mejor manera de hacer una lista de un generador o cualquier otra X iterable no es [x for x in X], sino más bien list(X)).

Alex Martelli
fuente
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

Ahora h = list(enumerate(xrange(2000, 2005), 1))funciona

Jochen Ritzel
fuente
6

enumerar es trivial y, por lo tanto, volver a implementarlo para aceptar un inicio:

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

Tenga en cuenta que esto no rompe el código usando enumerate sin argumento de inicio. Alternativamente, este oneliner puede ser más elegante y posiblemente más rápido, pero rompe otros usos de enumerate:

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

Lo último era pura tontería. @Duncan tiene la envoltura correcta.


fuente
Sí, sin sentido total. Algo en este sentido funcionaría, por ejemplo, en Haskell (el curry es lo más natural en ese idioma, y ​​debido a su pereza, una función que toma una lista es muy similar a una expresión generadora g). Pero eso no me disculpa, usuario de Python desde hace mucho tiempo, escribiendo BS. Gracias por mencionarlo.
5
>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]
PINCHAZO
fuente
enumerar debe ser un generador. crear una lista completa a la vez solo para repetir si a menudo no es aceptable
John La Rooy
Generalizado: inicio = 4 lista (enumerar (rango (inicio) + rango (1999, 2005))) [inicio:]
Tony Veijalainen
Sin embargo, el rango está en la lista en 2.52
Tony Veijalainen
3

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

Chris B.
fuente
1
No puede hacer esto en Python 2.5. El parámetro de inicio se introdujo en Python 2.6: docs.python.org/library/functions.html#enumerate . También menciona esto en la pregunta.
Mark Byers
Respondí esto antes de la edición inicial, cuando el código no estaba formateado y el problema me parecía ser el uso de un generador en lugar de una lista.
Chris B.
++: esa es la manera de hacerlo
Nas Banov
2

Ok, me siento un poco estúpido aquí ... ¿cuál es la razón para no hacerlo con algo así
[(a+1,b) for (a,b) in enumerate(r)]? Si no va a funcionar, tampoco hay problema:

>>> 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)]
Nas Banov
fuente
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)]

Como esto es algo detallado, recomiendo escribir su propia función para generalizarla:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))
Eli Courtwright
fuente
2
enumerar debe ser un generador. crear una lista completa a la vez solo para repetir si a menudo no es aceptable
John La Rooy
0

No sé cómo estas publicaciones podrían hacerse más complicadas que las siguientes:

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