ordenación de listas sin distinción entre mayúsculas y minúsculas, sin minúsculas el resultado?


133

Tengo una lista de cadenas como esta:

['Aden', 'abel']

Quiero ordenar los elementos, sin distinción entre mayúsculas y minúsculas. Entonces quiero obtener:

['abel', 'Aden']

Pero obtengo lo contrario con sorted()o list.sort(), porque las mayúsculas aparecen antes que las minúsculas.

¿Cómo puedo ignorar el caso? He visto soluciones que implican minúsculas todos los elementos de la lista, pero no quiero cambiar el caso de los elementos de la lista.


Respuestas:


192

En Python 3.3+ existe el str.casefoldmétodo diseñado específicamente para la coincidencia sin mayúsculas y minúsculas:

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

En Python 2 use lower():

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

Funciona para cadenas normales y unicode, ya que ambas tienen un lowermétodo.

En Python 2 funciona para una combinación de cadenas normales y unicode, ya que los valores de los dos tipos se pueden comparar entre sí. Sin embargo, Python 3 no funciona así: no puede comparar una cadena de bytes y una cadena Unicode, por lo que en Python 3 debe hacer lo correcto y solo ordenar las listas de un tipo de cadena.

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

11
Se puede evitar el viaje de ida y vuelta de la función lambda (Python 3) usando la str.lowerfunción general as sorted(lst, key=str.lower)o (Python 2) usando el lowermétodo del stringmódulo como sorted(lst, key=string.lower). También se puede usar str.lowerpara cadenas en Python 2, pero luego se tendría que usar unicode.lowerpara unicodeobjetos, mientras que se string.loweraceptan ambas (lo cual, como se dice, probablemente no sea realmente un modo de operación "sensato").
Daniel Andersson

Esto no funcionaría para una lista como ['Z', 'B', 'a', 'b', 'A'], que se clasifica como ['a', 'A', 'B', 'b', 'Z']. La 'B' mayúscula aparece antes de la 'b' minúscula porque sort () y sorted () de Python conservan el orden original cuando las cadenas coinciden. En este caso, se considera que la 'B' mayúscula coincide con la 'b' minúscula cuando se usa el plegado en mayúsculas. Esto siempre sucede si convierte mayúsculas y minúsculas para comparar: ordenado (spam, clave = str.lower) o ordenado (spam, clave = str.upper) o ordenado (spam, clave = str.casefold).
PJ Singh

Pruebe esta solución en su lugar: stackoverflow.com/a/1098160/10668287 . Clasificará ['Aden', 'aden'] correctamente como ['aden', 'Aden'].
PJ Singh

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

En Python 3 stres Unicode, pero en Python 2 se puede utilizar este enfoque más general que funcione para ambos stry unicode:

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

Gracias. Sé que debería haber mencionado esto antes, pero he oído que hay un problema con el uso de este método en una cadena Unicode (Py2). ¿Sabes algo de eso?

Todos son unicode. ¡Gracias! Una pregunta más, cómo hacerlo en una lista como esta:[['Aden'], ['abel']]

¿Cada lista solo tiene un elemento? Si es asísorted(x,key=lambda i:i[0].lower())
modifíquelo

Bueno, también podría tener algunas otras cosas, que no deberían usarse para la clasificación.

1
No importa, parece que estaba equivocado, la clasificación funciona para una combinación de cadenas y unicode, me confundieron con una pregunta anterior donde las tuplas también se incluyeron en el orden.
jamylak

10

También puede intentar esto para ordenar la lista en el lugar:

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


3

En python3 puedes usar

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

1

Lo hice de esta manera para 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]

Entonces puedes llamar a esta función:

sortCaseIns(yourListToSort)

0

Clasificación sin distinción entre mayúsculas y minúsculas, ordenando la cadena en su lugar , en Python 2 O 3 (probado en Python 2.7.17 y 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']

La clave es key=str.lower. Así es como se ven esos comandos con solo los comandos, para copiar y pegar fácilmente para que pueda probarlos:

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

Tenga en cuenta que si sus cadenas son cadenas Unicode, sin embargo (como u'some string'), solo en Python 2 (NO en Python 3 en este caso) el x.sort(key=str.lower)comando anterior fallará y generará el siguiente error:

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

Si obtiene este error, actualice a Python 3, donde manejan la clasificación unicode, o convierta sus cadenas unicode a cadenas ASCII primero, usando una comprensión de lista, como esta:

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

Referencias

  1. https://docs.python.org/3/library/stdtypes.html#list.sort
  2. Convierta una cadena Unicode en una cadena en Python (que contiene símbolos adicionales)
  3. https://www.programiz.com/python-programming/list-comprehension

-3

Prueba esto

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)

Salida

['abel', 'Aden']


9
Esta solución es exagerada e ilegible cuando basta una sola línea. Esto podría ser más aceptable en un lenguaje que no sea Python.
IceArdor
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.