Cara Lebih Pythonic untuk Menjalankan Proses X Kali

90

Mana yang lebih pythonic?

While loop:

count = 0
while count < 50:
    print "Some thing"
    count = count + 1

Untuk loop:

for i in range(50):
    print "Some thing"

Sunting: bukan duplikat karena ini memiliki jawaban untuk menentukan mana yang lebih jelas, vs. bagaimana menjalankan rentang tanpa 'i' - meskipun itu akhirnya menjadi yang paling elegan

Lionel
sumber
8
Upvoting untuk mengkompensasi suara yang tidak diberikan: jika Lionel menanyakan pertanyaan ini, orang lain mungkin memiliki pertanyaan yang sama, dan jawaban di bawah akan berguna.
Eric O Lebigot
2
Istilah "Pythonic" digunakan secara berlebihan. Ini adalah sinonim untuk "dapat dibaca" dan "mudah dimengerti". Setidaknya dengan Python.
darioo
Kemungkinan duplikat dari Apakah mungkin menerapkan Python untuk rentang loop tanpa variabel iterator?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

112

Sendiri:

for _ in range(50):
    print "Some thing"

jika Anda tidak membutuhkannya i. Jika Anda menggunakan Python <3 dan Anda ingin mengulang loop berkali-kali, gunakan xrangekarena tidak perlu membuat seluruh daftar sebelumnya.

Felix Kling
sumber
15
Hati-hati karena _ sedang dipetakan ke fungsi terjemahan gettext.
Gintautas Miliauskas
Terima kasih atas jawaban ini; ini adalah alasan utama saya tidak menggunakan for-loop karena saya memiliki variabel yang tidak digunakan di "i".
Lionel
6
_ sama seperti variabel lainnya. Hanya di REPL yang memiliki signifikansi tertentu. OP mungkin juga bertahan i.
vezult
2
@vezult Saya suka ini karena menjelaskan bahwa variabel tidak digunakan dalam pernyataan. Apakah mungkin ada alasan yang membayangi ini untuk tetap dengan i?
ryanjdillon
6
Saya sangat percaya dalam menambahkan kuda poni, terutama bila kedengarannya sesuai ... untuk kuda poni dalam kisaran (50): print ("neigh") #python 3
Paul
3

Perulangan for jelas lebih pythonic, karena menggunakan fungsionalitas bawaan tingkat tinggi Python untuk menyampaikan apa yang Anda lakukan dengan lebih jelas dan ringkas. Overhead range vs xrange, dan menugaskan yang tidak digunakani variabel yang , berasal dari tidak adanya pernyataan seperti pernyataan Verilog repeat. Alasan utama untuk tetap menggunakan solusi for adalah cara lain yang lebih kompleks. Contohnya:

from itertools import repeat

for unused in repeat(None, 10):
    del unused   # redundant and inefficient, the name is clear enough
    print "This is run 10 times"

Menggunakan repeat daripada range di sini kurang jelas karena ini bukan fungsi yang begitu terkenal, dan lebih kompleks karena Anda perlu mengimpornya. Panduan gaya utama jika Anda memerlukan referensi adalah PEP 20 - Zen of Python dan PEP 8 - Panduan Gaya untuk Kode Python .

Kami juga mencatat bahwa versi for range adalah contoh eksplisit yang digunakan baik dalam referensi bahasa dan tutorial , meskipun dalam hal ini nilainya digunakan. Ini berarti bentuknya pasti lebih familiar daripada perluasan while gaya-C for loop.

Yann Vernier
sumber
Bukankah lebih baik menggunakan hal yang diulang secara langsung, yaitu: for s in repeat('This is run 10 times', 10): print s??
F1Rumors
Pasti! Tetapi cetakan dalam kode contoh hanyalah contoh dari bagian kode yang berulang, yang mungkin tidak ada objek pusatnya.
Yann Vernier
Pengembang inti Python mengatakan ini lebih cepat daripada menggunakan range() twitter.com/raymondh/status/1144527183341375488
Chris_Rands
Memang lebih cepat, karena tidak perlu mencari atau membuat intobjek yang berbeda untuk setiap iterasi. Namun, waktu programmer mungkin lebih berharga daripada waktu eksekusi.
Yann Vernier
2

Jika Anda mencari efek samping yang terjadi dalam loop, saya pribadi akan memilih range() pendekatan.

Jika Anda peduli tentang hasil dari fungsi apa pun yang Anda panggil dalam loop, saya akan mencari pemahaman atau mappendekatan daftar. Sesuatu seperti ini:

def f(n):
    return n * n

results = [f(i) for i in range(50)]
# or using map:
results = map(f, range(50))
knutin
sumber
Hasil = (f untuk i dalam jarak (50))
Luka Rahne
1
hasil = itertools.imap (f, range (50))
Luka Rahne
@ralu, hanya jika Anda tidak memerlukan akses berulang atau acak ke hasil.
aaronasterling
2
hasil = tupel (hasil) dan jauh lebih cepat daripada daftar, karena mengiris pada tupel adalah O (1)
Luka Rahne
-3

Bagaimana tentang?

while BoolIter(N, default=True, falseIndex=N-1):
    print 'some thing'

atau dengan cara yang lebih jelek:

for _ in BoolIter(N):
    print 'doing somthing'

atau jika Anda ingin mengetahui waktu terakhir melalui:

for lastIteration in BoolIter(N, default=False, trueIndex=N-1):
    if not lastIteration:
        print 'still going'
    else:
        print 'last time'

dimana:

class BoolIter(object):

    def __init__(self, n, default=False, falseIndex=None, trueIndex=None, falseIndexes=[], trueIndexes=[], emitObject=False):
        self.n = n
        self.i = None
        self._default = default
        self._falseIndexes=set(falseIndexes)
        self._trueIndexes=set(trueIndexes)
        if falseIndex is not None:
            self._falseIndexes.add(falseIndex)
        if trueIndex is not None:
            self._trueIndexes.add(trueIndex)
        self._emitObject = emitObject


    def __iter__(self):
        return self

    def next(self):
        if self.i is None:
            self.i = 0
        else:
            self.i += 1
        if self.i == self.n:
            raise StopIteration
        if self._emitObject:
            return self
        else:
            return self.__nonzero__()

    def __nonzero__(self):
        i = self.i
        if i in self._trueIndexes:
            return True
        if i in self._falseIndexes:
            return False
        return self._default

    def __bool__(self):
        return self.__nonzero__()
DangerMouse
sumber
-5

Tidak ada cara yang benar-benar pythonic untuk mengulangi sesuatu. Namun, ini cara yang lebih baik:

map(lambda index:do_something(), xrange(10))

Jika Anda perlu meneruskan indeks, maka:

map(lambda index:do_something(index), xrange(10))

Pertimbangkan bahwa ia mengembalikan hasil sebagai koleksi. Jadi, jika Anda perlu mengumpulkan hasilnya, itu bisa membantu.

Abi M. Sangarab
sumber
Tidak hanya ini tidak benar-benar lebih baik (overhead panggilan fungsi, ekspresi lambda yang kurang dikenal, mengumpulkan hasil yang tidak digunakan dalam daftar), 10 juga bukan merupakan iterable.
Yann Vernier
Ya, xrange (10) bukan 10. Saya berkata lebih baik karena Anda tidak perlu menulis fungsi atau membuat loop. Namun, seperti yang saya katakan tidak ada cara pythonic yang nyata. Saya mengubah kodenya, Terima kasih.
Abi M. Sangarab