Eveti benim aklıma da ilk bu gelmişti, ama tersi olmasından biryere varamıyoruz sanırım.
Bunun için resmi dökümandan gösterebileceğiniz bir yer var mı? Merak ettim. Ayrıca birden fazla parametre ile çalışmıyor sanırım.
Buldum:
The parentheses can be omitted on calls with only one argument.
1 Beğeni
Peki şu kodu daha kısalta bilir miyiz arkadaşımla iddaya girdikte
def factorial(n):
return __import__("functools").reduce(lambda x,y:x*y, range(1,n+1))
from math import factorial
Bu olabilir
f = lambda x:1 if x == 0 else x*f(x-1)
1 Beğeni
evet şunun kısaltımı:
def factorial(n):
if n == 0:
return 1
else:
return n*factorial(n-1)
peki bu fonksiyon ile şunun bitme sürelerini nasıl karşılaştıracağım
def factorial(n):
return __import__("functools").reduce(lambda x,y:x*y, range(1,n+1))
Şöyle basit bir deneme yapınca, reduce coğunlukla daha hızlı çalışıyor gibi görünüyor.
import timeit
code1 = """
def factorial(n):
return __import__("functools").reduce(lambda x,y:x*y, range(1,n+1))
factorial(600)
"""
code2 = """
f = lambda x:1 if x == 0 else x*f(x-1)
f(600)
"""
print("reduce: {} sn".format(timeit.timeit(code1,number=1000)))
print("lambda: {} sn".format(timeit.timeit(code2,number=1000)))
ama şöyle yapınca durum farklı oluyor lambda fonksiyonun uzun hali daha hızlı
import timeit
code1 = """
def factorial(n):
return __import__("functools").reduce(lambda x,y:x*y, range(1,n+1))
factorial(600)
"""
code2 = """
def factorial(n):
if n == 0:
return 1
else:
return n* factorial(n-1)
"""
print("reduce: {} sn".format(timeit.timeit(code1,number=1000)))
print("ikici: {} sn".format(timeit.timeit(code2,number=1000)))
Olmadı dis modülünü kullanın.
1 Beğeni
Burada nasıl kullanmamız gerekiyor? Basit bir örnekle açıklayabilme şansınız var mı?
Bu çıktıların ne anlama geldiğini öğrenmek için buraya bakabilirsiniz:
from timeit import timeit
from dis import dis
from functools import reduce
from math import factorial as f5
def f(n):
return __import__("functools").reduce(lambda x,y:x*y, range(1,n+1))
def f2(n):
return reduce(lambda x,y:x*y, range(1,n+1))
def f3(n):
if n == 0:
return 1
else:
return n* f3(n-1)
f4 = lambda x:1 if x == 0 else x*f4(x-1)
print("reduce ( + import): {} sn".format(timeit("f(600)", number=1000, globals = globals())))
print("reduce: {} sn".format(timeit("f2(600)", number=1000, globals = globals())))
print("normal: {} sn".format(timeit("f3(600)", number=1000, globals = globals())))
print("lambda: {} sn".format(timeit("f4(600)", number=1000, globals = globals())))
print("math: {} sn".format(timeit("f5(600)", number=1000, globals = globals())))
def kodu_yaz(f, s):
print("\n\n"+ "-"*30 + "\n" + s + "\n\n")
dis(f)
kodu_yaz(f, "reduce ( + import)")
kodu_yaz(f2, "reduce")
kodu_yaz(f3, "normal")
kodu_yaz(f4, "lambda")
##kodu_yaz(f5, "math") # gömülü fonksiyon olduğu için çalışmaz
Normal olarak math.factorial
yaklaşık 10 kat daha hızlı, bu yüzden gömülü fonksiyonlar kullanıyoruz.
1 Beğeni
Teşekkür ederim, elinize sağlık Math modülünün C dilinde yazılması da ek olarak hız sağlamış olabilir.
1 Beğeni
Ee yani. Asıl sebep o zaten.
1 Beğeni
peki c ile yazılmış bir modül nasıl pythona aktarılıyor
Python yorumlayıcısı da C ile yazıldığı için çok zor olmuyor. Eğer yazacağınız fonksiyon basit parametreler alacaksa (int, char) normal bir şekilde DLL oluşturup ctypes aracılığı ile kullanabilirsiniz. Ama en iyisi Python’un C API’yını kullanmaktır, zaten çoğunlukla başka seçenek kalmıyor. Daha ayrıntılı bilgi için bu linkelere bakın:
https://docs.python.org/3/extending/extending.html
https://docs.python.org/3/extending/building.html
peki diğer dillerdede durum böylemi mesela ruby de