Python'da fonksiyon içinde listeyi yeniden atama

Merhabalar, Python’da bir listedeki tüm sayıları (int olanları) [listenin içinde başka listeler de olsa onların içindekini de toplayan] toplayan bir fonksiyon yazmaya çalışıyorum ama karşıma nasıl çözeceğime beynimin yetmediği sorunlardan bahsedeyim:

def ic_ice_toplam(v):
    bos=[]
    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam(eleman)
        elif isinstance(eleman,int):
            bos.append(eleman)
    return sum(bos)

Burada gördüğünüz gibi bos adlı listeyi fonksiyon içinde tanımladığımda 8. satırdaki iç içe fonksiyonu devreye girince fonksiyon her açıldığında bos listesini sıfırladığından bir işe yaramıyor. Bunu çözmek için bos adlı listeyi fonksiyonun dışında tanımladığımda ise fonksiyon çalıştıktan sonra çıkan değer bos’un içine kaydedildiğinden dolayı fonksiyon sonraki çalışmalarında o değeri de toplamın üstüne ekliyor.
bunu çözmek için ise şunu yapmayı denedim:

bos=[]
def ic_ice_toplam(v):
    # bos=[]
    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam(eleman)
        elif isinstance(eleman,int):
            bos.append(eleman)
    else:
        bos1=bos[::]
        bos=[]

    return sum(bos1)

bunu yapıp denediğimde fonksiyonu tanımlarken sorun çıkmıyor ama fonksiyonu bir yerde çağırdığımda bana bos.append(eleman) yazılı kodu göstererek şu hatayı veriyor: "UnboundLocalError: local variable ‘bos’ referenced before assignment"
bunu nasıl çözebilirim yani fonksiyon her çalışmasından sonra bos adlı listeyi nasıl sıfırlattırabilirim?

fonksiyona başka bir parametre ekleyerek, kendisini her çağrışında bos listesini de argüman olarak yollayabilirsiniz.

def ic_ice_toplam(v, bos=[]):
    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam(eleman, bos)
        elif isinstance(eleman,int):
            bos.append(eleman)
    return sum(bos)

liste = [[1, [2]], 3, [4, [5], 6], [[7]]]

sonuc = ic_ice_toplam(liste)

print(sonuc)
28
2 Beğeni

Oncelikle cok duzgun sorulmus bu soru icin tesekkurler.

Burada bos’un lokal bir degisken oldugunu zannediyor. Tipki yukaridaki koddaki gibi, sanki global olarak tanimlanmamis gibi. (Asagida bosu tanimlayan bos=[] kodundan once bos.append kullandigimiz icin laf ediyor.) Fonksiyonun basina bir adet global bos koyunca calisiyor:

bos=[]
def ic_ice_toplam(v):
    global bos

    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam(eleman)
        elif isinstance(eleman,int):
            bos.append(eleman)

    return sum(bos)

…ama sadece bir kere. Cunku her calismadan once bos’u sifirlamak lazim:

bos = []
def ic_ice_toplam_(v):
    global bos

    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam_(eleman)
        elif isinstance(eleman,int):
            bos.append(eleman)

    return sum(bos)

def ic_ice_toplam(v):
    global bos
    bos=[]
    return ic_ice_toplam_(v)

print(ic_ice_toplam([1, 2, "3", [4, 5], 6, [[7], [8, [9]]]])) #42
print(ic_ice_toplam([1, 2, "3", [4, 5], 6, [[7], [8, [9]]]])) #42

Fakat daha iyisi fonksiyona kullanacagi bosu arguman olarak vermek:

def ic_ice_toplam_(v, bos):
    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            ic_ice_toplam_(eleman, bos)
        elif isinstance(eleman,int):
            bos.append(eleman)

    return sum(bos)

def ic_ice_toplam(v):
    return ic_ice_toplam_(v, [])

print(ic_ice_toplam([1, 2, "3", [4, 5], 6, [[7], [8, [9]]]]))
print(ic_ice_toplam([1, 2, "3", [4, 5], 6, [[7], [8, [9]]]]))

Burada da oyle yapilmak istenmis fakat guvenilmemesi gereken default deger sistemine guvenilmis.

Bu arada neden elemanlarin kendilerini tutuyoruz?

def ic_ice_toplam(v):
    toplam = 0
    for eleman in v:
        if isinstance(v,str):
            continue
        elif isinstance(eleman,list):
            toplam += ic_ice_toplam(eleman)
        elif isinstance(eleman,int):
            toplam += eleman

    return toplam
5 Beğeni

Hocam bu kod hala bos u sıfırlamıyor üstüne ekliyor

Hocam en son yazdığınız kod en sadesi ve sanırım en kullanışlısı teşekkür ederim.
hepinize ufkumu açtığınız için teşekkür ederim

1 Beğeni