Sonucu küçültmeden büyük / küçük harf duyarlı liste sıralaması?


135

Bunun gibi dizelerden oluşan bir listem var:

['Aden', 'abel']

Öğeleri büyük / küçük harfe duyarlı olarak sıralamak istiyorum. Bu yüzden şunu almak istiyorum:

['abel', 'Aden']

Ama tam tersini sorted()veya ile alıyorum list.sort()çünkü büyük harf küçük harften önce görünüyor.

Vakayı nasıl görmezden gelebilirim? Tüm liste öğelerini küçültmeyi içeren çözümler gördüm, ancak liste öğelerinin durumunu değiştirmek istemiyorum.


Bu eğitici çok yararlıdır: docs.python.org/3/howto/sorting.html#sortinghowto
ady

Yanıtlar:


195

Python 3.3+ sürümünde, kasasız str.casefoldeşleştirme için özel olarak tasarlanmış bir yöntem vardır:

sorted_list = sorted(unsorted_list, key=str.casefold)

Python 2'de lower()şunları kullanın :

sorted_list = sorted(unsorted_list, key=lambda s: s.lower())

Her ikisinin de bir loweryöntemi olduğu için hem normal hem de unicode dizeler için çalışır .

Python 2'de, iki türün değerleri birbiriyle karşılaştırılabildiğinden, normal ve unicode dizelerin bir karışımı için çalışır. Yine de Python 3 böyle çalışmaz: bir bayt dizesini ve bir unicode dizesini karşılaştıramazsınız, bu nedenle Python 3'te mantıklı bir şey yapmalı ve yalnızca bir tür dizeden oluşan listeleri sıralamanız gerekir.

>>> lst = ['Aden', u'abe1']
>>> sorted(lst)
['Aden', u'abe1']
>>> sorted(lst, key=lambda s: s.lower())
[u'abe1', 'Aden']

11
Bir lambda fonksiyonu gidiş dönüş önlemek (Python 3) genel kullanılarak str.lowerolarak işlev sorted(lst, key=str.lower)ya da (Python 2) kullanılarak loweryöntemini stringmodülü olarak sorted(lst, key=string.lower). Bir de kullanabilirsiniz str.lowerPython 2'de dizeleri, ancak daha sonra kullanması gerekir unicode.loweriçin unicodenesneler, oysa string.lower(senin deyiminle olsa da, gerçekten muhtemelen operasyon "aklı başında" modu olmayan,) ikisi kabul eder.
Daniel Andersson

Bu, ['a', 'A', 'B', 'b' şeklinde sıralayan ['Z', 'B', 'a', 'b', 'A'] gibi bir liste için çalışmaz, Z '']. Büyük 'B' küçük 'b' harfinden önce görünür çünkü Python'un sort () ve sıralı () dizeleri eşleştiğinde orijinal sırayı korur. Bu durumda, büyük harf 'B'nin büyük harf kullanımı sırasında' b 'küçük harfiyle eşleştiği kabul edilir. Sıralı (spam, anahtar = str.lower) veya sıralı (spam, key = str.upper) veya sıralı (spam, key = str.casefold) karşılaştırmak için durumu dönüştürürseniz bu her zaman olur.
PJ Singh

Bunun yerine şu çözümü deneyin: stackoverflow.com/a/1098160/10668287 . ['Aden', 'aden'] doğru şekilde ['aden', 'Aden'] olarak sıralayacaktır.
PJ Singh

46
>>> x = ['Aden', 'abel']
>>> sorted(x, key=str.lower) # Or unicode.lower if all items are unicode
['abel', 'Aden']

Python 3'te strunicode vardır, ancak Python 2'de her ikisi için de çalışan bu daha genel yaklaşımı kullanabilirsiniz strve unicode:

>>> sorted(x, key=lambda s: s.lower())
['abel', 'Aden']

Teşekkür ederim. Bundan daha önce bahsetmem gerektiğini biliyorum, ancak bu yöntemi bir unicode dizesinde (Py2) kullanırken bir sorun olduğunu duydum. Bunun hakkında bir şey biliyor musun?

Hepsi unicode. Teşekkürler! Bir soru daha, bunun gibi bir listede nasıl yapılır:[['Aden'], ['abel']]

Her listede yalnızca bir öğe var mı? Öyleyse, biraz değiştirin:sorted(x,key=lambda i:i[0].lower())
jamylak

Pekala, başka şeyler de olabilir, ancak bunlar sıralama için kullanılmamalıdır.

1
Boşver, yanlışmışım gibi görünüyor, sıralama hem string hem de unicode karışımı için çalışıyor, tupl'lerin de sıralamaya dahil edildiği önceki bir soruyla kafam karışmıştı.
jamylak

10

Listeyi yerinde sıralamak için şunu da deneyebilirsiniz:

>>> x = ['Aden', 'abel']
>>> x.sort(key=lambda y: y.lower())
>>> x
['abel', 'Aden']


3

Python3'te kullanabilirsiniz

list1.sort(key=lambda x: x.lower()) #Case In-sensitive             
list1.sort() #Case Sensitive

1

Python 3.3 için bu şekilde yaptım:

 def sortCaseIns(lst):
    lst2 = [[x for x in range(0, 2)] for y in range(0, len(lst))]
    for i in range(0, len(lst)):
        lst2[i][0] = lst[i].lower()
        lst2[i][1] = lst[i]
    lst2.sort()
    for i in range(0, len(lst)):
        lst[i] = lst2[i][1]

O zaman bu işlevi çağırabilirsiniz:

sortCaseIns(yourListToSort)

0

Büyük / küçük harfe duyarlı olmayan sıralama, dizeyi yerinde sıralama, Python 2 VEYA 3'te (Python 2.7.17 ve Python 3.6.9'da test edilmiştir):

>>> x = ["aa", "A", "bb", "B", "cc", "C"]
>>> x.sort()
>>> x
['A', 'B', 'C', 'aa', 'bb', 'cc']
>>> x.sort(key=str.lower)           # <===== there it is!
>>> x
['A', 'aa', 'B', 'bb', 'C', 'cc']

Anahtar şudur key=str.lower. Kopyalayıp yapıştırmayı kolaylaştırmak için bu komutların yalnızca komutlarla nasıl göründüğü aşağıda açıklanmıştır, böylece onları test edebilirsiniz:

x = ["aa", "A", "bb", "B", "cc", "C"]
x.sort()
x
x.sort(key=str.lower)
x

Dizeleriniz unicode dizeleriyse, ancak (gibi u'some string'), o zaman yalnızca Python 2'de (bu durumda Python 3'te DEĞİL) yukarıdaki x.sort(key=str.lower)komutun başarısız olacağını ve aşağıdaki hatayı vereceğini unutmayın:

TypeError: descriptor 'lower' requires a 'str' object but received a 'unicode'

Bu hatayı alırsanız, ya unicode sıralamayı işledikleri Python 3'e yükseltin ya da aşağıdaki gibi bir liste anlayışı kullanarak önce unicode dizelerinizi ASCII dizelerine dönüştürün:

# for Python2, ensure all elements are ASCII (NOT unicode) strings first
x = [str(element) for element in x]  
# for Python2, this sort will only work on ASCII (NOT unicode) strings
x.sort(key=str.lower)

Referanslar:

  1. https://docs.python.org/3/library/stdtypes.html#list.sort
  2. Bir Unicode dizesini Python'da bir dizeye dönüştürme (ekstra semboller içerir)
  3. https://www.programiz.com/python-programming/list-comprehension

-3

Bunu dene

def cSort(inlist, minisort=True):
    sortlist = []
    newlist = []
    sortdict = {}
    for entry in inlist:
        try:
            lentry = entry.lower()
        except AttributeError:
            sortlist.append(lentry)
        else:
            try:
                sortdict[lentry].append(entry)
            except KeyError:
                sortdict[lentry] = [entry]
                sortlist.append(lentry)

    sortlist.sort()
    for entry in sortlist:
        try:
            thislist = sortdict[entry]
            if minisort: thislist.sort()
            newlist = newlist + thislist
        except KeyError:
            newlist.append(entry)
    return newlist

lst = ['Aden', 'abel']
print cSort(lst)

Çıktı

['abel', 'Aden']


9
Bu çözüm aşırıdır ve tek satırlık bir hat yeterli olduğunda okunamaz. Bu, Python dışındaki bir dilde daha kabul edilebilir olabilir.
IceArdor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.