Cara menghitung rentang angka mulai dari 1

154

Saya menggunakan Python 2.5, saya ingin enumerasi seperti itu (mulai dari 1 bukannya 0):

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

Saya tahu di Python 2.6 Anda dapat melakukan: h = enumerate (range (2000, 2005), 1) untuk memberikan hasil di atas tetapi dalam python2.5 Anda tidak bisa ...

Menggunakan python2.5:

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

Apakah ada yang tahu cara untuk mendapatkan hasil yang diinginkan di python 2.5?

Terima kasih,

Jeff

JeffTaggary
sumber
4
Hanya ingin tahu, karena saya seseorang yang belum melakukan banyak hal di jalan Python secara profesional. Apakah Anda terbatas pada Python 2.5 karena perusahaan Anda tidak ingin melakukan peningkatan karena alasan kompatibilitas?
Sean
2
Semua versi 2.x kompatibel ke belakang, jadi itu bukan alasan.
Jochen Ritzel
Katakan itu pada beberapa modul - ada beberapa di luar sana yang bekerja di Py 2.5 tetapi tidak di Py 2.6
xorsyst

Jawaban:

179

Seperti yang telah Anda sebutkan, ini mudah dilakukan di Python 2.6 atau yang lebih baru:

enumerate(range(2000, 2005), 1)

Python 2.5 dan yang lebih lama tidak mendukung startparameter jadi Anda bisa membuat dua objek rentang dan zip mereka:

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

Hasil:

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

Jika Anda ingin membuat generator alih-alih daftar maka Anda dapat menggunakan izip sebagai gantinya.

Mark Byers
sumber
menggunakan izipdan xrangeakan lebih dekat untuk menyebutkan
John La Rooy
7
Jawaban ini sudah ketinggalan zaman, sekarang Anda dapat menempatkan hanya enumerate(iterable, start=1)pada Python 2.6.
Fredrick Brennan
@ frb: Apakah Anda membaca pertanyaan? Dia sudah tahu solusi untuk Python 2.6. Dia secara khusus meminta solusi yang berfungsi di Python 2.5.
Mark Byers
1
@MarkByers Ternyata saya buta :) Sangat menyesal tentang itu. (Ini adalah # 1 di Google untuk "menghitung mulai dari 1")
Fredrick Brennan
2
@ 8chan ya, saya baru saja di sini dari pencarian google "apakah menghitung mulai dari nol python" :)
baxx
166

Hanya untuk meletakkan ini di sini demi anak cucu, di 2.6 parameter "mulai" ditambahkan ke enumerasi seperti:

enumerate(sequence, start=1)

dhackner
sumber
26
Perhatikan bahwa ini tidak melewatkan item pertama dalam daftar, ini mengimbangi indeks dengan nilai awal, sehingga Anda akan mendapatkan array di luar batas jika Anda melakukan sesuatu seperti: sequence[i]dalam kode Anda.
phyatt
14

Mudah, cukup tentukan fungsi Anda sendiri yang melakukan apa yang Anda inginkan:

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

Python 3

Dokumentasi resmi: enumerate(iterable, start=0)

Jadi Anda akan menggunakannya seperti ini:

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

Cara paling sederhana untuk dilakukan di Python 2.5 persis seperti yang Anda tanyakan:

import itertools as it

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

Jika Anda ingin daftar, seperti yang terlihat, gunakan zipsebagai pengganti it.izip.

(BTW, sebagai aturan umum, cara terbaik untuk membuat daftar dari generator atau X lain yang bisa diubah bukan [x for x in X] , tetapi sebaliknya list(X)).

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

Sekarang h = list(enumerate(xrange(2000, 2005), 1))bekerja.

Jochen Ritzel
sumber
6

enumerate itu sepele, dan begitu juga mengimplementasikannya untuk menerima permulaan:

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

Perhatikan bahwa ini tidak memecahkan kode menggunakan enumerate tanpa argumen mulai. Atau, oneliner ini mungkin lebih elegan dan mungkin lebih cepat, tetapi tidak menggunakan enumerasi lainnya:

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

Yang terakhir adalah omong kosong. @Uncan punya pembungkus yang benar.


sumber
Yap, omong kosong total. Sesuatu di sepanjang garis ini akan benar-benar berfungsi misalnya Haskell (kari adalah hal yang paling alami dalam bahasa itu, dan karena kemalasannya, fungsi mengambil daftar sangat mirip dengan generator expressg). Tapi itu tidak permisi - pengguna python lama - menulis BS. Terima kasih telah menunjukkannya.
5
>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]
TUSUKAN
sumber
menghitung harus menjadi generator. membuat seluruh daftar sekaligus hanya untuk beralih jika sering tidak dapat diterima
John La Rooy
Generalized: start = 4 list (enumerate (range (start) + range (1999, 2005))) [mulai:]
Tony Veijalainen
Namun kisarannya adalah 2,52
Tony Veijalainen
3

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

Chris B.
sumber
1
Dia tidak bisa melakukan ini dengan Python 2.5. Parameter awal diperkenalkan dalam Python 2.6: docs.python.org/library/functions.html#enumerate . Dia juga menyebutkan ini dalam pertanyaan.
Mark Byers
Menjawab ini sebelum edit awal, ketika kode tidak diformat dan masalahnya bagi saya adalah penggunaan generator, bukan daftar.
Chris B.
++: itulah cara untuk melakukannya
Nas Banov
2

Ok, saya merasa sedikit bodoh di sini ... apa alasannya untuk tidak melakukannya dengan sesuatu seperti
[(a+1,b) for (a,b) in enumerate(r)]? Jika Anda tidak akan berfungsi, tidak ada masalah juga:

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

Karena ini agak bertele-tele, saya sarankan menulis fungsi Anda sendiri untuk menggeneralisasi:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))
Eli Courtwright
sumber
2
menghitung harus menjadi generator. membuat seluruh daftar sekaligus hanya untuk beralih jika sering tidak dapat diterima
John La Rooy
0

Saya tidak tahu bagaimana pos-pos ini dapat dibuat lebih rumit daripada yang berikut ini:

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