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


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.


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)


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

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

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


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.


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.


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

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


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

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.