Nasıl başlayan sayıların bir dizi numaralandırmak için 1


154

Python 2.5 kullanıyorum, şöyle bir numaralandırma istiyorum (0 yerine 1'den başlayarak):

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

Python 2.6'da şunları yapabilirsiniz: h = numaralandırmak (aralık (2000, 2005), 1) yukarıdaki sonucu vermek için ama python2.5'te yapamazsınız ...

Python2.5 kullanma:

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

Herkes python 2.5 istenen sonucu elde etmek için bir yol biliyor mu?

Teşekkürler,

Jeff


4
Sadece merak ediyorum, çünkü profesyonelce Python'un yolunda çok şey yapmadı. Şirketiniz uyumluluk nedeniyle yükseltme yapmak istemediğinden Python 2.5 ile sınırlı mısınız?
Sean

2
Tüm 2.x sürümleri geriye dönük olarak uyumludur, bu nedenle bir sebep yoktur.
Jochen Ritzel

Bunu bazı modüllere söyleyin - Py 2.5'de çalışan ancak Py 2.6'da olmayan birkaç tane var
xorsyst

Yanıtlar:


179

Daha önce de belirttiğiniz gibi, bu Python 2.6 veya daha yeni sürümlerde yapmak kolaydır:

enumerate(range(2000, 2005), 1)

Python 2.5 ve sonraki sürümler startparametreyi desteklemez, bunun yerine iki aralık nesnesi oluşturabilir ve bunları sıkıştırabilirsiniz:

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

Sonuç:

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

Liste yerine jeneratör oluşturmak istiyorsanız izip kullanabilirsiniz .


kullanarak izipve xrangenumaralandırmaya daha yakın olur
John La Rooy

7
Bu cevap güncel değil, artık enumerate(iterable, start=1)Python 2.6'dan itibaren koyabilirsiniz .
Fredrick Brennan

@frb: Soruyu okudun mu? Python 2.6'nın çözümünü zaten biliyor. Özellikle Python 2.5'te çalışan bir çözüm istedi.
Mark Byers

1
@MarkByers Görünüşe göre körüm :) Bunun için gerçekten üzgünüm. (Bu, "1'den başlayarak numaralandırma" için Google'da 1
numaradır

2
@ 8chan yep, ben sadece google arama "sıfır python numaralandırma başlar" :)
baxx

166

Bunu buraya gelecek kuşak adına koymak için 2.6'da "start" parametresi şu şekilde numaralandırıldı:

enumerate(sequence, start=1)


26
Bunun listedeki ilk öğeyi atlamadığını, dizini başlangıç ​​değerine göre dengelediğini unutmayın, böylece sequence[i]kodunuzda şöyle bir şey yaparsanız sınırların dışına bir dizi alırsınız .
phyatt

14

Kolay, sadece istediğinizi yapan kendi işlevinizi tanımlayın:

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

12

Python 3

Resmi belgeler: enumerate(iterable, start=0)

Yani şöyle kullanırsınız:

>>> 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'te tam olarak ne istediğini yapmanın en basit yolu:

import itertools as it

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

Bir liste görmek istediğiniz gibi, zipyerine kullanın it.izip.

(BTW, genel bir kural olarak, bir jeneratörden veya başka bir yinelenebilir X'den bir liste yapmanın en iyi yolu değil [x for x in X] , aksine 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

Şimdi h = list(enumerate(xrange(2000, 2005), 1))çalışıyor.


6

numaralandırma önemsizdir ve bir başlangıcı kabul etmek için yeniden uygular:

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

Bunun, başlatma bağımsız değişkeni olmadan numaralandırma kullanarak kodu bozmadığını unutmayın. Alternatif olarak, bu oneliner daha zarif ve daha hızlı olabilir, ancak numaralandırmanın diğer kullanımlarını kırar:

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

İkincisi saf saçmalıktı. @Duncan ambalajı doğru buldu.


Evet, tamamen saçmalık. Bu çizgiler boyunca bir şey aslında örneğin Haskell'de işe yarayacaktır (körelme o dilde şimdiye kadarki en doğal şeydir ve tembelliğinden dolayı, liste alan bir işlev bir jeneratör ifadesine çok benzer). Ama bu beni - uzun süre python kullanıcısı - BS yazmak için mazeret değil. Gösterdiğiniz için teşekkürler.

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

numaralandırma bir jeneratör olmalıdır. sık sık kabul edilemezse tekrarlamak için bir kerede tüm bir liste oluşturma
John La Rooy

Genel: başlat = 4 liste (numaralandırma (aralık (başlangıç) + aralık (1999, 2005)))) [başlangıç:]
Tony Veijalainen

ancak aralık
2.52'de listeleniyor


2

Tamam, burada biraz aptal hissediyorum ... sadece böyle bir şeyle yapmamanın nedeni
[(a+1,b) for (a,b) in enumerate(r)]nedir? Çalışmazsanız, sorun da yok:

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

Bu biraz ayrıntılı olduğundan, genelleştirmek için kendi işlevinizi yazmanızı öneririm:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))

2
numaralandırma bir jeneratör olmalıdır. sık sık kabul edilemezse yinelemek için bir kerede tüm bir liste oluşturma
John La Rooy

0

Bu yazıların muhtemelen aşağıdakilerden sonra nasıl daha karmaşık hale getirilebileceğini bilmiyorum:

# Just pass the start argument to enumerate ...
for i,word in enumerate(allWords, 1):
    word2idx[word]=i
    idx2word[i]=word
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.