Najszybszym (i najłatwiejszym do zrozumienia) jest ze zrozumieniem listy.
Zobacz taktowania:
import timeit
import random
c=10000
class SomeObj:
def __init__(self, i):
self.attr=i
def loopCR():
l=[]
for i in range(c):
l.append(SomeObj(random.random()))
return l
def compCR():
return [SomeObj(random.random()) for i in range(c)]
def loopAc():
lAttr=[]
for e in l:
lAttr.append(e.attr)
return lAttr
def compAc():
return [e.attr for e in l]
t1=timeit.Timer(loopCR).timeit(10)
t2=timeit.Timer(compCR).timeit(10)
print "loop create:", t1,"secs"
print "comprehension create:", t2,"secs"
print 'Faster of those is', 100.0*abs(t1-t2)/max(t1,t2), '% faster'
print
l=compCR()
t1=timeit.Timer(loopAc).timeit(10)
t2=timeit.Timer(compAc).timeit(10)
print "loop access:", t1,"secs"
print "comprehension access:", t2,"secs"
print 'Faster of those is', 100.0*abs(t1-t2)/max(t1,t2), '% faster'
Drukuje:
loop create: 0.103852987289 secs
comprehension create: 0.0848100185394 secs
Faster of those is 18.3364670069 % faster
loop access: 0.0206878185272 secs
comprehension access: 0.00913000106812 secs
Faster of those is 55.8677438315 % faster
więc lista jest zarówno zrozumienie szybciej pisać i szybsze do wykonania.
"Skuteczny" jest w oku patrzącego ... –
@Pyson: Nie, nie jest, "efektywny" jest mierzony w złożoności, czasie obliczeń, liniach kodu i/lub pamięci. – Junuxx
@Junuxx: większość ludzi nie testuje każdego wystąpienia zrozumienia względem pętli, aby zobaczyć, która jest mniejsza liczba cykli procesora. Jeśli korzystasz z Pythona, prawdopodobnie chodzi o łatwość pisania i czytania - a nie bezwzględną szybkość. To, co tam napisałeś, czas obliczeń, linie kodu i/lub użycie pamięci, mogą być całkowicie sprzeczne. Podwójny kod może być szybszy i zużywa mniej pamięci, ale zajmuje więcej czasu, aby czytać i pisać jako programista. Który jest bardziej * wydajny *? Szybciej wykonać lub szybciej pisać w Pythonie? To jest mój punkt widzenia. –