Sortierung von Listen ohne Berücksichtigung der Groß- und Kleinschreibung, ohne das Ergebnis zu verkleinern?


133

Ich habe eine Liste solcher Zeichenfolgen:

['Aden', 'abel']

Ich möchte die Elemente sortieren, ohne die Groß- und Kleinschreibung zu berücksichtigen. Also möchte ich bekommen:

['abel', 'Aden']

Aber ich bekomme das Gegenteil mit sorted()oder list.sort(), weil Großbuchstaben vor Kleinbuchstaben erscheinen.

Wie kann ich den Fall ignorieren? Ich habe Lösungen gesehen, bei denen alle Listenelemente verkleinert werden, aber ich möchte die Groß- und Kleinschreibung der Listenelemente nicht ändern.


Dieses Tutorial ist sehr hilfreich: docs.python.org/3/howto/sorting.html#sortinghowto
Ady

Antworten:


192

In Python 3.3+ gibt es die str.casefoldMethode, die speziell für das Caseless Matching entwickelt wurde:

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

Verwenden Sie in Python 2 lower():

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

Es funktioniert sowohl für normale als auch für Unicode-Zeichenfolgen, da beide eine lowerMethode haben.

In Python 2 funktioniert es für eine Mischung aus normalen und Unicode-Zeichenfolgen, da die Werte der beiden Typen miteinander verglichen werden können. Python 3 funktioniert jedoch nicht so: Sie können eine Byte-Zeichenfolge und eine Unicode-Zeichenfolge nicht vergleichen. In Python 3 sollten Sie also das Vernünftige tun und nur Listen eines Zeichenfolgentyps sortieren.

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

11
Man kann die Lambda-Funktion Roundtrip vermeiden, indem man (Python 3) die allgemeine str.lowerFunktion as sorted(lst, key=str.lower)oder (Python 2) die lowerMethode des stringModuls as verwendet sorted(lst, key=string.lower). Man kann auch str.lowerfür Strings in Python 2 verwenden, müsste dann aber unicode.lowerfür unicodeObjekte verwenden, während string.lowerbeide akzeptiert werden (was, wie Sie sagen, wahrscheinlich keine wirklich "vernünftige" Funktionsweise ist).
Daniel Andersson

Dies würde für eine Liste wie ['Z', 'B', 'a', 'b', 'A'] nicht funktionieren, die nach ['a', 'A', 'B', 'b', sortiert ist. 'Z']. Das Großbuchstaben 'B' wird vor dem Kleinbuchstaben 'b' angezeigt, da Pythons sort () und sorted () die ursprüngliche Reihenfolge beibehalten, wenn die Zeichenfolgen übereinstimmen. In diesem Fall wird angenommen, dass das Großbuchstaben 'B' mit dem Kleinbuchstaben 'b' übereinstimmt, wenn casefold verwendet wird. Dies geschieht immer, wenn Sie Groß- und Kleinschreibung konvertieren, um zu vergleichen: sortiert (Spam, Schlüssel = str.lower) oder sortiert (Spam, Schlüssel = str.upper) oder sortiert (Spam, Schlüssel = str.casefold).
PJ Singh

Versuchen Sie stattdessen diese Lösung: stackoverflow.com/a/1098160/10668287 . Es wird ['Aden', 'Aden'] korrekt als ['Aden', 'Aden'] sortieren.
PJ Singh

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

In Python 3 strist Unicode, aber in Python 2 können Sie diesen allgemeineren Ansatz verwenden, der sowohl für strals auch für unicode:

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

Danke dir. Ich weiß, ich hätte das schon früher erwähnen sollen, aber ich habe gehört, dass es ein Problem bei der Verwendung dieser Methode für eine Unicode-Zeichenfolge (Py2) gibt. Weißt du etwas darüber?

Sie sind alle Unicode. Vielen Dank! Noch eine Frage, wie es auf einer Liste wie dieser geht:[['Aden'], ['abel']]

Hat jede Liste nur einen Eintrag? Wenn ja, ändern Sie es einfach ein wenig zu:sorted(x,key=lambda i:i[0].lower())
Jamylak

Nun, es könnte auch andere Dinge geben, die jedoch nicht zum Sortieren verwendet werden sollten.

1
Egal, es scheint, ich habe mich geirrt, die Sortierung funktioniert für eine Mischung aus String und Unicode. Ich war verwirrt mit einer früheren Frage, bei der auch Tupel in die Sortierung aufgenommen wurden.
Jamylak

10

Sie können dies auch versuchen, um die Liste direkt zu sortieren:

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


3

In Python3 können Sie verwenden

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

1

Ich habe es für Python 3.3 so gemacht:

 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]

Dann können Sie einfach diese Funktion aufrufen:

sortCaseIns(yourListToSort)

0

Sortierung ohne Berücksichtigung der Groß- und Kleinschreibung, Sortieren der Zeichenfolge an Ort und Stelle in Python 2 ODER 3 (getestet in Python 2.7.17 und Python 3.6.9):

>>> 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']

Der Schlüssel ist key=str.lower. So sehen diese Befehle nur mit den Befehlen aus, damit Sie sie einfach kopieren und testen können:

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

Beachten Sie, dass, wenn Ihre Zeichenfolgen Unicode-Zeichenfolgen sind (wie u'some string'), der obige x.sort(key=str.lower)Befehl nur in Python 2 (in diesem Fall NICHT in Python 3) fehlschlägt und den folgenden Fehler ausgibt:

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

Wenn dieser Fehler auftritt, führen Sie entweder ein Upgrade auf Python 3 durch, wo die Unicode-Sortierung durchgeführt wird, oder konvertieren Sie Ihre Unicode-Zeichenfolgen zuerst in ASCII-Zeichenfolgen. Verwenden Sie dazu ein Listenverständnis wie folgt:

# 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)

Verweise:

  1. https://docs.python.org/3/library/stdtypes.html#list.sort
  2. Konvertieren Sie eine Unicode-Zeichenfolge in eine Zeichenfolge in Python (mit zusätzlichen Symbolen).
  3. https://www.programiz.com/python-programming/list-comprehension

-3

Versuche dies

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)

Ausgabe

['abel', 'Aden']


9
Diese Lösung ist übertrieben und nicht lesbar, wenn ein Einzeiler ausreicht. Dies ist möglicherweise in einer anderen Sprache als Python akzeptabler.
IceArdor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.