Türkçe Karakterler Sort Metodu ile Listenin Sonunda sıralanıyor

Merhaba başka bir forumda bir soru gözüme çarptı orda verilen cevapların hepsini ayri ayri uyguladım ama bende de sonuç değişmedi. Bu sorun nasil cozumlenir.
PyCharm kullaniyorum.


Sorun : Turkce karakterlerin alfabetik siralanmamasi

sehirler =['Çorum', 'İstanbul', 'Samsun', 'Ankara', 'Çorum', 'İzmir', 'Samsun', 'Ankara']

sehirler.sort()

['Ankara', 'Ankara', 'Samsun', 'Samsun', 'Çorum', 'Çorum', 'İstanbul', 'İzmir']


cevap :
Sıralamayı alfabetik sırayla yapıyor ancak latin alfabesi olarak, diğer harfleri latin harfleri bittikten sonra sıralıyor.

bunu düzeltmek için sort yapmadan aşağıdaki kodu çalıştırmanı öneririm:

import locale
locale.setlocale(locale.LC_ALL, 'Turkish_Turkey.1254')

Çalışmaz ise 'Turkish_Turkey.1254'yerine 'tr_TR', 'tr_TR.UTF-8', 'tr_TR.ISO8859-9' birini dene. Sistemlere göre farklı sonuç verebiliyor.
1 Beğeni

locale'ı setlemek yetmiyor, sort'un key parametresine de local.strxfrm vermek gerekir

>>> help(locale.strxfrm)
Help on built-in function strxfrm in module _locale:

strxfrm(...)
    strxfrm(string) -> string.

    Return a string that can be used as a key for locale-aware comparisons.
>>> sehirler = ["Çorum", "İstanbul", "Samsun", "Ankara", "Çorum", "İzmir"]
>>> sehirler.sort(key=locale.strxfrm)
>>> sehirler
['Ankara', 'Çorum', 'Çorum', 'İstanbul', 'İzmir', 'Samsun']

https://docs.python.org/3/howto/sorting.html#odd-and-ends

4 Beğeni

Düz listede çalışıyor yalnız aşağıdaki gibi tuple içeren bir listeyi ada göre sıralamak istersem

import locale
locale.setlocale(locale.LC_ALL, 'tr_TR.utf8')
newStudents = [
    ("Veli", "F", 10),
    ("Ömer", "A", 98),
    ("Rıza", "C", 78),
]

newStudents.sort(key=locale.strxfrm)

şu hatayı alıyorum :

TypeError: strxfrm() argument 1 must be str, not tuple

Lambda ile key girdiğimde sıralama oluyor ama Türkçe (locale) kullanamıyorum.

name = lambda names:names[0]
newStudents.sort(key=name)

Böyle bir sıralamayı nasıl yaparım ?

newStudents = [
    ("Veli", "F", 10),
    ("Ömer", "A", 98),
    ("Rıza", "C", 78),
]
sirali_liste = newStudents.copy()
def harfler(harf):
    global alfabe
    for i,h in enumerate("abcçdefgğhıijklmnoöprsştuüvyz"):
        if h == harf:
            return i
        else:
            pass
for i in newStudents:
    siralama = 0
    for b in newStudents:
        if harfler(i[0][0].lower()) > harfler(b[0][0].lower()):
            siralama += 1
    sirali_liste.insert(siralama,i)

del sirali_liste[len(newStudents):]
print(sirali_liste)

Böyle birşey yaptım, tek sıkıntısı sıralamayı ilk harfe göre yapması aynı harfle başlayan iki kelime olunca sıkıntı çıkabilir bu yüzden.

Aradan çok zaman geçmiş çeşitli çözümler üretilmiş.

Computer gibi düşünelim.

Bir işletim sisteminde karakterler bir kod sayfasıyla eşleştirilip sonrasında görüntülenir.

Şimdi kod sayfaları, ascii code, ansi code vs anlatmaya gerek yok.

Sıralama algoritmaları da temelde bilgisayar gibi olaya bakar.

Ve işletim sisteminin ve karakter sisteminin dertleri ile uğraşmaz, kullandığınız sıralma algoritması büyük küçüğe matematiksel bakar.

Ve kullandığınız her işletim sisteminin dilini kod sayfasını karakter setini denetleme, sıralama algoritmanızı buna göre düzenlemek sıkıcı geldi açıkcası.

Basit bir yol izleyin.

Dict kullanın.

Yani karakterlerinizi rakamlarla eşleştirin sonra rakamları sıralayın sonra da tekrar rakmaların harf karşılığını yazıdırın. Bu durumda kod sayfası vs çok dert etmek gerekmez.

Kod çalışıyor mu denemedim bile,

ChatGPT ye rica ettim bir kod yazdı. Doğru çalışmasa bile mantığı anlamak açısında örnek çıkaracak kadar vardır diye düşünüyorum.

# Harf-rakam eşleştirmelerini içeren sözlük
harf_rakam_dict = {'a': 3, 'b': 1, 'c': 2, 'd': 4}

# Sıralanacak kelimeler listesi
kelimeler = ['cab', 'bad', 'abc', 'dba']

# Kelimeleri sıralamak için bir işlev tanımlama
def sirala_kelimeler(kelime):
    return [harf_rakam_dict[harf] for harf in kelime]

# Sıralama işlemi
sirali_kelimeler = sorted(kelimeler, key=sirala_kelimeler)

# Sıralı kelimeleri yazdırma
print("Sıralı Kelimeler:")
for kelime in sirali_kelimeler:
    print(kelime)

Her zaman karakter dizileri, harfler vs olarak düşünmeyim.

Her türlü karşılaştırmanın ve işlemin sayı olarak varolduğunu düşünerek çalışmak karmaşayı önleyecektir.

import locale
locale.setlocale(locale.LC_ALL, 'tr_TR.utf8')
newStudents = [
    ("Veli", "F", 10),
    ("Ömer", "A", 98),
    ("Rıza", "C", 78),
]
key = lambda n: locale.strxfrm(n[0])
newStudents.sort(key=key)

print(newStudents)