Yeni bir fonksiyon oluşturmak yerine, bir for döngüsü içindeki global fonksiyonu değiştirmenin bir yolu var mı?

Bu soruyu stackoverflow’da da sordum ama henüz cevap gelmedi. Belki buradaki arkadaşlar cevap verebilir.

Çalışan kod hakkında

Aşağıdaki kodları çalıştırdığımda, beklendiği gibi çalıştıklarını görüyorum.

def modify_string(n):
    str1 = ", ".join([f"arg{i}" for i in range(n)])
    str2 = f"func{len(str1.split(', ')) - 1}"\
        f"({', '.join(str1.split(', ')[:-1])})"
    return f"lambda {str1}: list(map(lambda i: list({str2})," \
        f" range({str1.split(', ')[-1]})))"


def create_globals(n):
    global func1
    func1 = lambda x: list(map(lambda j: 0, range(x)))
    for i in range(2, n + 1):
        globals()[f"func{i}"] = eval(modify_string(i)) 


create_globals(3)
print(func3(3, 2, 4))

Çıktı:

[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

create_globals (n) işlevi çağrıldığında, n farklı fonksiyon tanımlanır. Fonksiyonların isimleri i numarasına göre değişmektedir. Oluşturulan her fonksiyon, bir sonraki adımda oluşturulacak fonksiyonun argümanı olur:

for döngüsünün ilk aşamasında, aşağıdaki fonksiyon tanımlanır:

func2 = lambda arg0, arg1: list(map(lambda i: list(func1(arg0)), range(arg1)))

for döngüsünün ikinci aşamasında, aşağıdaki fonksiyon tanımlanır:

func3 = lambda arg0, arg1, arg2: list(map(lambda i: list(func2(arg0, arg1)), range(arg2)))

Yani bu, n boyutlu matrisler oluşturan bir fonksiyondur.

Soru hakkında

Yapmaya çalıştığım şey, her adımda fonksiyonun aynı global adını kullanarak yeni fonksiyonlar tanımlamaktı. Ve nihayet oluşturulan son fonksiyonu kullanmak istemiştim. Bu yüzden kodları aşağıdaki gibi değiştirdim:

def modify_string(n):
    str1 = ", ".join([f"arg{i}" for i in range(n)])
    str2 = f"func({', '.join(str1.split(', ')[:-1])})"
    return f"lambda {str1}: list(map(lambda i: list({str2})," \
        f" range({str1.split(', ')[-1]})))"


def create_globals(n):
    global func
    func = lambda x: list(map(lambda j: 0, range(x)))
    for i in range(2, n + 1):
        globals()["func"] = eval(modify_string(i))
        print("func =", modify_string(i))


create_globals(3)

Çıktı:

func = lambda arg0, arg1: list(map(lambda i: list(func(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func(arg0, arg1)), range(arg2)))

Çıktı beklendiği gibi görünüyor. Ancak func(3, 2, 4) gibi bir fonksiyon çağırdığımda, bir TypeError alıyorum.

func = lambda arg0, arg1: list(map(lambda i: list(func(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func(arg0, arg1)), range(arg2)))
Traceback (most recent call last):
  File "./a.py", line 21, in <module>
    func(2, 3, 4)
  File "<string>", line 1, in <lambda>
  File "<string>", line 1, in <lambda>
TypeError: <lambda>() missing 1 required positional argument: 'arg2'

arg2 yazmış olmama rağmen, yorumlayıcı arg2 eksikmiş gibi tepki veriyor. Bunun neden olduğunu açıklayabilir misiniz?

Şimdiden teşekkür ederim.

3 Beğeni

Birisi şöyle bir cevap vermiş, çok boyutlu matris oluşturmanın çok daha kısa bir yolu varmış. Bunu düşünememiştim ben.

def mat(*n):
    return [mat(*n[:-1]) for _ in range(n[-1])] if n else 0
3 Beğeni

çok faydalı bir kod benim için fakat nasıl çalıştığını anlayamadım açıklayabilir misiniz ? bayağı kullanışlı çünkü.

1 Beğeni
# Şimdi diyelim fonksiyonu aşağıdaki gibi çağırdık.     
mat(2, 3)
# Fonksiyonun içinde gerçekleşen 1. adımda
# eğer n argümanı veriliyse, bir liste, eğer verili değilse 
# 0 geri dönderilir.
# 1. adım'da bir liste geri dönderilecek.
# Listenin içine bakıyoruz. Öz yinelemeli bir fonksiyon var. 
# for _ in range(n[-1]) yazılmış: Son elemanımız 3, yani 3 
# kere recursion yapılacak
# 1. recursion:
    # son eleman alınmadan fonksiyon tekrar çağrılır.
    # Fonksiyon tekrar n argümanının verili olup olmadığına bakar, 
    # eğer veriliyse yine bir liste dönderir, eğer n argümanı 
    # verili değilse, 0 geri dönderilir.
    # Bakıyoruz, n argümanımız (2, )'ye eşit. Yani yine 
    # bir liste dönderilecek.
    # Bu sefer for _ in range(n[-1]) ifadesi, n[-1] 2 olduğu için 2 kere
    # öz yineleme yapacak.
    # 1.1. recursion:
        # son eleman alınmadan fonksiyon çağrılır.
        # Fonksiyon tekrar n argümanının verili olup olmadığına bakar,
        # Bu sefer n argümanı verili değildir.
        # O zaman fonksiyon bir 0 sayısı geri dönderir.
    # 1.2. recursion:
        # 1.1'de olan işlemin aynısı burda da olur, yine
        # bir 0 sayısı geri dönderilir.
    # 1. recursion sonunda [0, 0] gibi bir verimiz olur.
        
# 2. recursion'da olan 1. recursionda olan işlemin aynısı olur.
# Bu işlemin sonunda yine [0, 0] verisini elde ederiz.

# 3. recursion'da da 1. recursionda olan işlemin aynısı olur.
# Bu işlemin sonunda yine [0, 0] verisini elde ederiz.

# 3. recursionun sonunda elde edeceğimiz veri yapısı
# şuna benzeyecektir.
# [[0, 0], [0, 0], [0, 0]]

Aşağıdaki fonksiyonu çalıştırın isterseniz.

import time

def mat(*n):
    result = [mat(*n[:-1]) for _ in range(n[-1])] if n else 0
    print(result, n)
    time.sleep(1)
    return result
3 Beğeni

çok teşekkür ederim :slight_smile: