String bir isimle değişken oluşturma

Mesela şöyle bir kod yazacağım

input("İsim")=10
print(d1)

kodu çalıştırdığımda isim yazıp benden değer isteyecek bende atıyorum d1 yazacağım bana 10 değerini vermesini istiyorum çalıştığında .
Yani kullanıcıdan aldığım string verinin adına değişken oluşturup değer atayacağım.
Bu mümkün müdür ?

Mümkündür, ama önerilen bir yaklaşım değil.

globals()["hello"] = 1
print(hello)

Bu ifadenin yerine, şu tavsiye ediliyor.

d = {"hello": 1}
print(d["hello"])

Burada hello yerine input'u koyabilirsiniz,

globals()[x := input("> Degisken ismi ne olsun? ")] = input("> Degiskenin değeri ne olsun?")
print("Degisken ismi", x)
print("Degisken değeri", eval(x))

ama dediğim gibi değişkenleri bu şekilde türetmek pek önerilen bir yaklaşım değil.

1 Beğeni

Tamam teşekkür ederim ne gibi bir sakıncası varki ilki gibi üretmenin

Örnek ile umarım daha rahat anlaşılır. Oluşabilecek en büyük sorun identifier’ın inşaası ile (construction), çalışması arasında (execution) bağlantının kurulamaması sorunudur.

Mesela aşağıdaki program sorunsuz bir şekilde çalışıyor.

def create_func(n):
    str1 = ", ".join([f"arg{i}" for i in range(n)])
    str2 = f"func{len(str1.split(', ')) - 1}({', '.join(str1.split(', ')[:-1])})"
    return f"lambda {str1}: list(map(lambda i: list({str2}), 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(create_func(i))
        print("func =", create_func(i))


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

Bu programı çalıştırırsanız, ekrana şöyle bir çıktının yazdırılması gerekir:

func = lambda arg0, arg1: list(map(lambda i: list(func1(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func2(arg0, arg1)), range(arg2)))
[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

Çıktıya bakarsanız, aslında döngünün her bir aşamasında, bir fonksiyon inşa edildiğini ve o inşa edilen fonksiyon bir sonraki fonksiyonun inşasında kullanıldığını görürsünüz. Ve en sonunda da 3 * 2 * 4 boyutlarına sahip 3 boyutlu bir matris oluşturabiliyoruz.

Peki, ben func1, func2 şeklinde, her bir fonksiyonun bilgisini ayrı bir identifier’da tutmak istemeyip, tek bir identifier ismi kullanarak bu işlemi yapmak istiyorum diyelim. Yani sürekli func()'u kullanarak sonunda 3 boyutlu bir dizi elde etmeye çalışıyorum, bakalım başarılı olabilecek miyim.

def create_func(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}), 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(create_func(i))
        print("func =", create_func(i))


create_globals(3)

func(3, 2, 4)

Bu kodları çalıştırdığım zaman aldığım çıktı da aşağıdaki gibi oluyor:

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 "C:\Users\tanberk\Desktop\Python\test.py", line 18, in <module>
    print(func(3, 2, 4))
          ^^^^^^^^^^^^^
  File "<string>", line 1, in <lambda>
  File "<string>", line 1, in <lambda>
TypeError: <lambda>() missing 1 required positional argument: 'arg2'

arg2 yazdığım halde arg2'yi yazmadığımı belirten bir hata ile karşılaşıyorum. Neden böyle oluyor? Çünkü, tek isim altında oluşturduğum her bir fonksiyon çağrıldığında önceki inşaatlara değil, son inşaata atıfta bulunuyor.

Üretilen fonksiyonları karşılaştırın:

  1. programın ürettiği fonksiyonlar:
func = lambda arg0, arg1: list(map(lambda i: list(func1(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func2(arg0, arg1)), range(arg2)))
  1. programın ürettiği fonksiyonlar:
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)))

Fonksiyonlar benzer ancak dediğim gibi, fonksiyonun inşaası ile çalıştırılması arasında bağlantı sağlamak ikinci örnekte mümkün olmadı.

Değişkenleri, birden çok değişkeni tutabilen veri tiplerinde tutmak varken identifier üretmek ile uğraşmak daha zahmetli ve bug üretmeye daha müsait. Ki globals()'e bakarsanız aslında onun da bir dict olduğunu görürsünüz. Duruma göre list, set, dict, tuple, verilerinizi tutacağınız veri tipleri olacaktır.

Eğer amacım ilk programın ürettiği n boyutlu diziler üretmekse, daha güvenilir algoritmalar bulmam gerekir.

Değişken ismi olarak x girersek eval’a istediğimizi gönderebiliyoruz.


if input() == "d1":
	print(10)
2 Beğeni