Liste-Sözlük Biri Beni Kurtarsın!

Merhaba foruma yeni üye oldum ve listelerdeki indeks metodunun bir benzerini yazmaya çalışıyorum. Program bir listedeki tekrarlamayan öğeleri alıp bir sözlüğe anahtar olarak atayıp, karşılarına liste içerisindeki indeks numaralarını liste olarak alacak. Bunun için kodları yazdım. Hatta mantık hatası da bulamıyorum ama tam listeleri sözlük içerine aktaracağım sırada listeleri boş olarak atıyor.

lst=[1,2,3,4,5,2,3,1,3,3,2,4,5]

s_ind=dict()

l_ind=list()

for i in range(len(lst)):

    if lst[i] in s_ind.keys():

        continue  

    l_ind.append(i)      

    for j in range(i+1,len(lst)):

        if lst[i]==lst[j]:

            l_ind.append(j)

    s_ind[lst[i]]=l_ind

    l_ind.clear()
  

print(s_ind)


Çıktı olarak şunu veriyor:
çıktııı
Araya listem doğru oluşmuş mu diye print kodu eklediğim zaman

lst=[1,2,3,4,5,2,3,1,3,3,2,4,5]

s_ind=dict()

l_ind=list()

for i in range(len(lst)):

    if lst[i] in s_ind.keys():

        continue  

    l_ind.append(i)      

    for j in range(i+1,len(lst)):

        if lst[i]==lst[j]:

            l_ind.append(j)

    print(l_ind) # Listem doğru oluştumu diye buraya yazdım

    s_ind[lst[i]]=l_ind

    l_ind.clear()

           

print(s_ind)

Listemin doğru oluştuğunu görüyorum fakat sözlükte ilgili yere aktarırken sorun oluşturuyor. Bunun sebebi nedir acaba?

Hatta problemi basitleştirip şöyle bir kod yazdığımda

lst=list()

soz=dict()

for i in range(5):

    lst.append(i)

    print(lst) #Listem burada yine olması gerektiği gibi oluşuyor.

    soz[i]=lst

print(soz)

Şu şekilde sonuç alıyorum. Liste her seferinde uzayarak gitmesi gerekirken hepsine en son listeyi atıyor. Bu tarz hatalar neden oluyor?

Bunun sebebi

kod parçasındaki print(soz) ifadesinin for bloğunun dışında kalmasıdır.


Sizin istediğiniz şey, bir dizinin elemanlarının anahtar ve indekslerinin de değer olarak sözlüğe kaydedilmesi ise şu tarz bir şey yapılabilir:

lst=[1,2,3,4,5,2,3,1,3,3,2,4,5]

def list_to_dict(array):
   
    index_dict = dict()
    for num, ele in enumerate(array):
        index_dict[ele] = num
    
    return index_dict
    
print(list_to_dict(lst))

Yalnız bu kod “Program bir listedeki tekrarlamayan öğeleri alıp bir sözlüğe anahtar olarak atayıp…” ifadesini karşılamıyor, “Program bir listedeki öğeleri anahtar, ilk görüldüğü indeksleri değer olarak atar.” işini görüyor.


Python’daki sözlük veri tipi bir anahtarı yalnızca bir defa tutar. Yani sozluk[5] = “beş” dedikten sonra, sozluk[5] = “bes” dersek, son güncelleme neyse onu kabul eder. O yüzden listeyi sözlüğe aktarırken, (tekrarlanan elemanın) en son indeksi neyse, bize de onu döndürür.
Eğer görüldüğü ilk indeksi almak istiyorsak, list_to_dict(array) fonksiyonunu tanımladıktan hemen sonra,
array = set(array) diyerek, küme sınıfının tekrarlı elemanları yok etmesi özelliğinden faydalanmamız lazım olur. Böylece bir eleman ikinci defa görülüyorsa bile biz ondan sözlüğe aktarmadan önce kurtulmuş oluruz.

2 Beğeni

Şöyle bir şey yapabilirsiniz:

lst = [1, 2, 3, 4, 5, 2, 3, 1, 3, 3, 2, 4, 5]
arr = set(lst)
print(dict(zip(arr, [[i] for i in range(len(arr))])))
> {1: [0], 2: [1], 3: [2], 4: [3], 5: [4]}

Daha kullanışlı olması açısından bir fonksiyon yaratırsak:

lst = [1, 2, 3, 4, 5, 2, 3, 1, 3, 3, 2, 4, 5]
def key_index(arr):
    arr = set(arr)
    return dict(zip(arr, [[i] for i in range(len(arr))]))
print(key_index(lst))
> {1: [0], 2: [1], 3: [2], 4: [3], 5: [4]}

Bu durumun sebebine gelecek olursak bence bunu bir debugging ile çok daha iyi anlayabilirsiniz.
Şöyle buyurun: RecApp-2022-05-31-10:55:02
Debugging’i izlediğinizde göreceksiniz ki listelerin boş olmasının sebebi

l_ind listesinde .clear() metodunu çağırmanız. Bu satırı silerek s_ind’e bakacak olursak…

{1: [0, 7, 1, 5, 10, 2, 6, 8, 9, 3, 11, 4, 12], 2: [0, 7, 1, 5, 10, 2, 6, 8, 9, 3, 11, 4, 12], 3: [0, 7, 1, 5, 10, 2, 6, 8, 9, 3, 11, 4, 12], 4: [0, 7, 1, 5, 10, 2, 6, 8, 9, 3, 11, 4, 12], 5: [0, 7, 1, 5, 10, 2, 6, 8, 9, 3, 11, 4, 12]}

Böyle bir çıktı görüyoruz. Yine beklediğimiz çıktı değil elbette çünkü kodunuzda bir mantık hatası var gibi görünüyor.

Açıkçası burada ne yapmaya çalıştığınızı anlayamadım. Muhtemelen kodunuz beklemediğiniz gibi çalıştı, belki de iç içe for loop kullanmak işleri biraz komplike etmiş olabilir…

4 Beğeni

Öncelikle verdiğiniz cevaplar için çok teşekkür ederim. Ben liste ve string metodlarını yazmak gibi bir hedef belirlediğim için set gibi yapılardan faydalanmak istemiyorum. Burada özellikle sormak istediğim şey şu:

Program

Şu kodu programın kodlarına eklediğimde yukarıdaki çıktıyı alıyorum. Yani her şey tam istediğim gibi çalışıyor aslında. Sözlükte tekrarlanmayan yapıları anahtar olarak atıyorum ve anahtarların karşısına eklemek istediğim listeyi de istediğim yerde oluşturuyorum. Fakat gelin görün ki

şu kod devreye girdiğinde zaten oluşturulmuş olan liste anahtara başarı ile aktarılamıyor.
Şunu soruyorum döngü içerisinde bir sözlüğe değer olarak liste girmek istiyorsak bu konuda hep sıkıntı mı yaşayacağız burada varsa gördüğünüz bir mantık hatası lütfen söyleyin.

def list_index(list):
    result ={}
    for i in list:
        if i not in result.keys():  
            result[i] = [list.index(i)]
    return result

print(list_index([56,26,78,31,45,26]))  

Anladıysam böyle bir şey mi yapmaya çalışıyorsunuz?

Benzeri hocam ama tüm liste öğelerin hangi indekslerde tutulduğunun bilgisini saklamak istiyorum.

Yani her anahtar bir defaya mahsus bulunacak şekilde tüm anahtarların endeksini istiyorsunuz. Yani şöyle:

liste = [56,26,78,31,45,26,66,56] 

Mesela 26 anahtarının karşılığı şöyle olacak:

{26:[1,5]}
def list_index(list):
    result ={}
    for index, i in enumerate(list):
        if i not in result.keys():  
            result[i] = [index]
        elif i in result.keys():
            result[i].append(index)
    return result
print(list_index([56,26,78,31,45,26])) 

Eğer dediğim gibiyse doğru çalışıyor olması lazım

1 Beğeni

evet yazmaya çalıştığım tam olarak bu teşekkür ederim.
Ben de kodlarım çalışmayınca enumerate kullanmayı düşündüm ama kodlarımda varsa bir hata onu bulmaya çalıştım.

2 Beğeni