2012-04-22 35 views
79

Tôi có một danh sách các chuỗi như thế này:phân loại danh sách phân biệt chữ hoa chữ thường, mà không làm giảm kết quả?

['Aden', 'abel'] 

Tôi muốn sắp xếp các mục, case-insensitive. Vì vậy, tôi muốn nhận được:

['abel', 'Aden'] 

Nhưng tôi nhận được đối diện với sorted() hay list.sort(), vì chữ hoa chữ thường xuất hiện trước.

Tôi làm cách nào để bỏ qua trường hợp này? Tôi đã nhìn thấy các giải pháp liên quan đến việc giảm tất cả các mục trong danh sách, nhưng tôi không muốn thay đổi trường hợp của các mục danh sách.

Trả lời

115

Các công trình sau đây bằng Python 2:

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

Nó hoạt động cho cả chuỗi bình thường và unicode, vì cả hai đều có phương thức lower.

Trong Python 2 nó hoạt động cho một kết hợp của chuỗi bình thường và unicode, vì giá trị của hai loại có thể được so sánh với nhau. Python 3 không hoạt động như thế, mặc dù: bạn không thể so sánh chuỗi byte và chuỗi unicode, vì vậy trong Python 3 bạn nên làm điều sane và chỉ sắp xếp danh sách của một loại chuỗi.

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

+1 Câu trả lời đúng nhưng Python 3 không hoạt động vì nó không có các kiểu khác nhau vì nó sử dụng unicode theo mặc định. – jamylak

+0

@jamylak: Câu trả lời có được chỉnh sửa sau đó, không còn đề cập đến Python 2 hoặc 3 không? – ArtOfWarfare

+1

Tôi đã làm rõ. Tôi hy vọng nó rõ ràng hơn bây giờ. –

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

Trong Python 3 str là unicode nhưng trong Python 2 bạn có thể sử dụng phương pháp tổng quát hơn này mà làm việc cho cả hai strunicode:

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

Cảm ơn bạn. Tôi biết tôi nên đã đề cập đến điều này trước đây, nhưng tôi đã nghe có một vấn đề với cách sử dụng phương pháp này trên một chuỗi unicode (Py2). Bạn có biết gì về điều đó không? –

+0

Tất cả đều là unicode. Cảm ơn! Một câu hỏi nữa, làm thế nào để làm điều đó trên một danh sách như thế này: '[['Aden'], ['abel']]' –

+0

Mỗi danh sách chỉ có một mục? Nếu vậy chỉ cần sửa đổi nó một chút để: 'sắp xếp (x, khóa = lambda i: i [0] .lower())' – jamylak

7

Bạn cũng có thể thử điều này:

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

Hãy thử

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 này

['abel', 'Aden']

+8

Giải pháp này là quá mức cần thiết và không thể đọc được khi một lớp lót đủ. Điều này có thể được chấp nhận hơn trong một ngôn ngữ khác ngoài Python. – IceArdor

1

tôi đã làm nó theo cách này cho Python 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] 

Sau đó, bạn chỉ có thể gọi chức năng này:

sortCaseIns(yourListToSort) 
2

Trong python3 bạn có thể sử dụng

list1.sort(key=lambda x: x.lower()) #Case In-sensitive    
list1.sort() #Case Sensitive 
Các vấn đề liên quan