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


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

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.


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.


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

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

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


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