2012-04-22 11 views
79

Mam listę ciągów takiego:sortowanie listy bez rozróżniania wielkości liter, bez obniżania wyniku?

['Aden', 'abel'] 

chcę sortować elementy, bez uwzględniania wielkości liter. Tak, chcę otrzymać:

['abel', 'Aden'] 

Ale pojawia się odwrotnie z sorted() lub list.sort(), bo wielkie pojawia się przed małymi literami.

Jak mogę zignorować sprawę? Widziałem rozwiązania, które wymagają obniżenia wszystkich elementów listy, ale nie chcę zmieniać wielkości pozycji na liście.

Odpowiedz

115

następujące prace w Pythonie 2:

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

Działa zarówno dla łańcuchów normalnych, jak i unikodowych, ponieważ oba mają metodę lower.

W języku Python 2 działa na kombinację ciągów normalnych i unikodowych, ponieważ wartości obu typów można porównać ze sobą. Python 3 nie działa tak, choć: nie można porównać ciąg bajtów i ciąg Unicode, więc w Pythonie 3 należy zrobić sane rzecz i tylko sortować listy jednego typu string.

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

+1 Prawidłowa odpowiedź, ale Python 3 działa, ponieważ nie ma różnych typów, ponieważ domyślnie używa standardu Unicode. – jamylak

+0

@jamylak: Czy odpowiedź powinna zostać zmieniona, aby już nie wspomnieć o Pythonie 2 lub 3? – ArtOfWarfare

+1

Zrobiłem wyjaśnienie. Mam nadzieję, że teraz jest jaśniej. –

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

W Pythonie 3 str jest Unicode, ale w Pythonie 2 można użyć tego bardziej ogólnego podejścia, które działa zarówno str i unicode:

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

Dziękuję. Wiem, że powinienem był o tym wspomnieć wcześniej, ale słyszałem, że jest problem z używaniem tej metody na łańcuchu Unicode (Py2). Czy wiesz coś o tym? –

+0

Wszystkie są Unicode. Dzięki! Jeszcze jedno pytanie, jak to zrobić na takiej liście: '[['Aden'], ['abel']]' –

+0

Czy każda lista ma tylko jeden przedmiot? Jeśli tak, po prostu zmodyfikuj go nieco do: 'posortowane (x, klucz = lambda i: i [0] .lower())' – jamylak

7

Można też spróbować:

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

Spróbuj

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) 

Output

['abel', 'Aden']

+8

To rozwiązanie jest przesadne i nieczytelne, gdy wystarczy jeden wiersz. Może to być bardziej akceptowalne w języku innym niż język Python. – IceArdor

1

zrobiłem to w ten sposób dla Pythona 3.3:

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] 

Wtedy właśnie można nazwać tę funkcję:

sortCaseIns(yourListToSort) 
2

W python3 można użyć

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