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.