Sözlüğün içeriği nasıl büyükten küçüğe sıralanır?

Elimde bir sözlük var:
Bu sözlük şu şekilde:
‘a’: 12,5
‘b’: 8,7

Bu sözlüğü, value’ların değer büyüklüğüne göre sıralayıp tekrar sözlüğe kaydetmek istiyorum. Şöyle bir şey buldum:

dict(sorted(self._readable_result.items(), key=lambda x: x[1], reverse=True))

Bu kod sadece sayının ilk basamağına bakıp ona göre sıralıyor yani b, a’dan önce geliyor. Büyük değerin ilk sıraya girmesini istiyorum bunu nasıl yapabilirim?

Bunu kaldirman lazim.

Hayır ornunla alakası yok. Bütün alfabeyi sözlük olarak alıyorsun. 9.8, 8.6 gibi değerler başa gelirken 12,5 gibi değerler ortalara geliyor. Kaldırırsam sıfırlar başa gelir.

for item in self._readable_result:
            if float(self._readable_result[item]) != 0:
                print(f"{item} : {self._readable_result[item]}%")

Bunun çıktısı şu şekilde yani:

a : 9.0%
t : 8.6%
n : 8.1%
o : 7.5%
r : 7.0%
i : 5.9%
s : 5.1%
d : 4.5%
l : 4.4%
h : 3.4%
y : 3.0%
m : 2.6%
u : 2.5%
f : 2.3%
p : 2.3%
g : 2.2%
c : 2.0%
e : 11.8%
b : 1.7%
P : 1.2%
v : 1.0%
w : 0.9%
T : 0.6%
x : 0.5%
C : 0.4%
I : 0.3%
j : 0.2%
L : 0.2%
k : 0.1%
z : 0.1%
A : 0.1%
E : 0.1%
F : 0.1%
M : 0.1%
R : 0.1%
S : 0.1%

e en çok oranı olan harf olmasına rağmen ortalarda gördüğün gibi. Sadece ilk basamağa bakıyor sıralarken. Bunu çözmeye çalışıyorum.

Zaten o kodun buyuk degeri basa getirmesi gerekmiyor mu?

In [1]: d = {'a': 12.5, 'b': 8.7, 'c':4.5}

In [2]: dict(sorted(d.items(), key=lambda x: x[1]))
Out[2]: {'c': 4.5, 'b': 8.7, 'a': 12.5}

In [3]: dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
Out[3]: {'a': 12.5, 'b': 8.7, 'c': 4.5}
In [4]: d = {'a': 12.5, 'b': 8.7, 'c':4.5, 'd': 16.3}

In [5]: dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
Out[5]: {'d': 16.3, 'a': 12.5, 'b': 8.7, 'c': 4.5}

In [8]: d = {'a': 12.5, 'd': 16.3, 'e': 16.2}

In [9]: dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
Out[9]: {'d': 16.3, 'e': 16.2, 'a': 12.5}

D, E’nin onunde, yani 16.3 16.2’den buyuk oldugu icin o daha onde. Ilk basamaga bakmiyor.


Burada self._readable_result’u buyukten kucuge siralamamissin.

1 Beğeni
class Frequance():
    
            
    def __init__(self, data, type='str'): # or type='file'
        self.alphabet = tuple(string.ascii_letters)
        self.__result = {char: 0 for char in self.alphabet}
        self._readable_result = self.__result
        self.__total = 0

        if type == 'str':
            self.__text = data
            for char in self.__text:
                if char in self.alphabet:
                    self.__result[char] += 1
        elif type == 'file':
            self.__file = data
            with open(self.__file) as file:
                while True:
                    char = file.read(1)
                    if char in self.alphabet:
                        self.__result[char] += 1
                    elif char == '':
                        break
        else:
            raise ValueError

        # Calculate total number of characther
        for i in self.__result.values():
            self.__total += i

        # Create ratio dictinoary
        for i in self.__result:
            self._readable_result[i] = format(self.__result[i] * 100 / self.__total, '.1f')  # ratio = x * 100 / total

        self._readable_result = dict(sorted(self._readable_result.items(), key=lambda x: x[1:], reverse=True))
    
    # Print result
    @property
    def result(self):
        for item in self._readable_result:
            if float(self._readable_result[item]) != 0:
                print(f"{item} : {self._readable_result[item]}%")
        

nygma = Frequance("text.txt", 'file')
print(nygma.result)

Kodun tamamı bu. Ben de çözemedim niye böyle bir sonuç verdiğini. Frekans analizi yapmak için oluşturdum bu sınıfı.

@property kullanirken uretilen sonucu dondurmen lazim, print etmemelisin oncelikle. print(nygma.result) kismi None print edecektir cunku fonksiyon hicbir sey dondurmemis.


Onun zaten float olmasi gerekmiyor muydu?


for key, value in self._readable_result.items():
1 Beğeni

Girdi dosyasini paylasmadigin icin (bkz: Soru Sorarken Sıkça Düşülen Hatalar #7) sozlugun degerlerinin string oldugunu anlamamiz vakit almis.

2 Beğeni

Daha güzel bir çözüm. Bu şekilde modifiye ettim:

# Print result
    def print_result(self):
        for key, value in self._readable_result.items():
            if float(value) != 0:
                print(f"{key} : {value}%")

Frekans analizi zaten string değerler için yapılır. Ama belirtmem daha güzel olurdu haklısınız.

Hayir, sozlukteki degerler string oldugu icin onlari sorted’a sokmadan once float’a cevirmen lazim.

key, value şeklinde düzelttikten sonra sorun düzeldi float olarak belirtmeme gerek kalmıyor. Ama hala neden sıralamayı yanlış yaptığını anlayamadım.

Vurguyu simdi ekledim

1 Beğeni

Sorun çözüldü. Problem sözlüğün değerlerinin str objesi olması. Yani sıralamayı sayıya göre değil utf-8 tablosunda ki sırasına göre sıralıyormuş.float olarak değiştirince düzeldi:

# Create ratio dictinoary
        for i in self.__result:
            self._readable_result[i] = float(format(self.__result[i] * 100 / self.__total, '.1f'))  # ratio = x * 100 / total