Apakah ada ekspresi generator lurus ke depan yang dapat menghasilkan elemen tak hingga?
Ini adalah pertanyaan teoritis murni. Tidak perlu jawaban "praktis" di sini :)
Misalnya, mudah membuat generator terbatas:
my_gen = (0 for i in xrange(42))
Namun, untuk membuat yang tak terbatas, saya perlu "mencemari" namespace saya dengan fungsi palsu:
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
Melakukan sesuatu dalam file terpisah dan import
-ing nanti tidak dihitung.
Saya juga tahu bahwa itertools.repeat
itulah tepatnya. Saya ingin tahu apakah ada solusi satu baris tanpa itu.
python
iterator
generator
infinite-loop
hugomg
sumber
sumber
my_gen
lalu lakukanmy_gen = my_gen()
.del _my_gen
jika Anda tidak ingin membingungkan keduanyaJawaban:
iter
= nilai callable + sentinel nol-argumenint()
selalu kembali0
Oleh karena itu,
iter(int, 1)
merupakan iterator tak terbatas. Jelas ada sejumlah besar variasi pada tema khusus ini (terutama setelah Anda menambahkannyalambda
ke dalam campuran). Salah satu varian dari catatan tertentu adalahiter(f, object())
, karena menggunakan objek yang baru dibuat sebagai nilai sentinel hampir menjamin iterator tak terbatas terlepas dari callable yang digunakan sebagai argumen pertama.sumber
iter
dengan propertiint
yang sering kali kita lupakan.itertools.count
:count = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
iter
-fungsi disebut dengan dua argumen, itu berperilaku sedikit berbeda dari biasanya:iter(callable, sentinel) -> iterator
. Argumen 1,callable
dipanggil untuk setiap iterasi dari iterator, hingga menghasilkan nilaisentinel
. Namun, seperti yangint()
akan selalu kembali0
, kita dapat meneleponint()
selamanya dan tidak pernah mencapai 1. Ini akan menghasilkan daftar tak terbatas dari0
'sitertools
menyediakan tiga generator tak terbatas:count(start=0, step=1)
: 0, 1, 2, 3, 4, ...cycle(p)
: p [0], p [1], ..., p [-1], p [0], ...repeat(x, times=∞)
: x, x, x, x, ...Saya tidak tahu ada orang lain di perpustakaan standar.
Karena Anda meminta satu baris:
sumber
∞
simbol untuk siapa pun yang bertanya-tanya - menghilangkan argumen membuat pengulangan berjalan selamanyaiter(int, 1)
mantera. Sayang sekaliitertools
tidak memilikiendlessly()
metode yang tujuan utamanya adalah melakukan ini;itertools.count()
juga tidak begitu mudah dibaca.Anda dapat mengulangi callable yang mengembalikan konstanta yang selalu berbeda dari sentinel iter ()
sumber
iter
(di sini dengan tambahan sentinel) dan sintakslambda
(di sini tanpa parameter yang lewat, hanyareturn 0
), satu-satunya tempat untuk dibenci adalah yang membingungkang1
.OS Anda mungkin menyediakan sesuatu yang dapat digunakan sebagai generator tak terbatas. Misal di linux
jelas ini tidak seefisien
sumber
\n
s yang muncul dari waktu ke waktu ... Licik! :)Tidak ada yang tidak secara internal menggunakan iterator tak terbatas lainnya yang didefinisikan sebagai kelas / fungsi / generator (bukan -ekspresi, fungsi dengan
yield
). Ekspresi generator selalu diambil dari iterable anoter dan tidak melakukan apa pun selain memfilter dan memetakan itemnya. Anda tidak dapat beralih dari item terbatas ke item tak terbatas hanya denganmap
danfilter
, Anda perluwhile
(ataufor
yang tidak berakhir, itulah yang sebenarnya tidak dapat kita gunakan hanyafor
dan iterator terbatas).Trivia: PEP 3142 secara dangkal mirip, tetapi setelah diperiksa lebih dekat tampaknya masih memerlukan
for
klausa (jadi tidak(0 while True)
untuk Anda), yaitu hanya menyediakan pintasan untukitertools.takewhile
.sumber
from itertools import repeat, count, cycle
mungkin dianggap "tersedia" bagi kebanyakan orang.iter
. Iterator tak terbatas sebenarnya tersedia sebagai bawaan - lihat jawaban saya :)Cukup jelek dan gila (namun sangat lucu), tetapi Anda dapat membuat iterator Anda sendiri dari ekspresi dengan menggunakan beberapa trik (tanpa "mengotori" namespace Anda seperti yang diperlukan):
sumber
Mungkin Anda bisa menggunakan dekorator seperti ini misalnya:
Penggunaan (1):
Penggunaan (2)
Saya pikir itu bisa lebih ditingkatkan untuk menyingkirkan mereka yang jelek
()
. Namun itu tergantung pada kompleksitas urutan yang ingin Anda buat. Secara umum jika urutan Anda dapat diekspresikan menggunakan fungsi, maka semua kerumitan dan sintaksis generator dapat disembunyikan di dalam dekorator atau fungsi seperti dekorator.sumber
def
dan closure? ;)(2^x)
, Anda dapat memiliki(x)
. Jika Anda meningkatkannya sedikit mungkin juga fibonacci, dll.seq
dan memasukkan kembali kode secara langsung kewrap