enumerate () - membuat generator dengan Python


90

Saya ingin tahu apa yang terjadi ketika saya meneruskan hasil dari fungsi generator ke enumerate () python. Contoh:

def veryBigHello():
    i = 0
    while i < 10000000:
        i += 1
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word

Apakah pencacahan diulangi dengan malas, atau apakah itu menyeruput semuanya menjadi yang pertama? Saya 99,999% yakin itu malas, jadi dapatkah saya memperlakukannya persis sama dengan fungsi generator, atau apakah saya perlu berhati-hati?


1
Saya kira Anda bermaksud menaikkan saya di veryBigHello.
— robert

@robert: jika saya tidak salah saya secara otomatis meningkat
— the_drow

@ the_drow Tidak dalam veryBigHellofungsi itu sendiri.
— Will McCutchen

1
@ Akan: Oh, benar. Tapi itu hanya rewel. Itu sebuah contoh. Tetap diperbaiki.
— the_drow

Jawaban:


108

Itu malas. Cukup mudah untuk membuktikan bahwa itu masalahnya:

>>> def abc():
...     letters = ['a','b','c']
...     for letter in letters:
...         print letter
...         yield letter
...
>>> numbered = enumerate(abc())
>>> for i, word in numbered:
...     print i, word
...
a
0 a
b
1 b
c
2 c

Apakah ini Python 2 atau 3 (atau keduanya)? Apakah malas di keduanya? Saya diuji pada Python 2 dan itu adalah malas.
— becko

2
Saya menguji ini pada Python 3.5.2, dan mengevaluasi dengan malas.
— gobernador

42

Bahkan lebih mudah untuk membedakannya daripada salah satu dari saran sebelumnya:

$ python
Python 2.5.5 (r255:77872, Mar 15 2010, 00:43:13)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> abc = (letter for letter in 'abc')
>>> abc
<generator object at 0x7ff29d8c>
>>> numbered = enumerate(abc)
>>> numbered
<enumerate object at 0x7ff29e2c>

Jika enumerate tidak melakukan evaluasi malas itu akan mengembalikan [(0,'a'), (1,'b'), (2,'c')]atau beberapa (hampir) setara.

Tentu saja, enumerate hanyalah generator mewah:

def myenumerate(iterable):
   count = 0
   for _ in iterable:
      yield (count, _)
      count += 1

for i, val in myenumerate((letter for letter in 'abc')):
    print i, val

2
Terima kasih atas penjelasannya. Saya mengalami sedikit kesulitan untuk mencari tahu jawaban yang diterima. Setidaknya sampai aku melihat milikmu.
— trendsetter37

13

Karena Anda dapat memanggil fungsi ini tanpa keluar dari pengecualian memori, fungsi ini jelas malas

def veryBigHello():
    i = 0
    while i < 1000000000000000000000000000:
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word

0

Alternatif jadul karena saya menggunakan generator yang ditulis orang lain (sklearn) yang tidak berfungsi dengan pendekatan di sini.

i=(-1)
for x in some_generator:
    i+=1
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.