Naturalmente, ordene una lista de tuplas alfanuméricas por el primer elemento de la tupla en Python

Una pregunta anterior de stackoverflow explica cómo ordenar una lista de cadenas alfanuméricamente. Me gustaría ordenar una lista de tuplas alfanuméricamente por el primer elemento de la tupla.

Ejemplo 1:

>>> sort_naturally_tuple([('b', 0), ('0', 1), ('a', 2)]) [('0', 1), ('a', 2), ('b', 0)] 

Ejemplo 2:

 >>> sort_naturally_tuple([('b10', 0), ('0', 1), ('b9', 2)]) [('0', 1), ('b9', 2), ('b10', 0)] 

Actualización: para enfatizar el factor alfanumérico, revise el ejemplo 2.

Usando la segunda respuesta de la otra pregunta, generalizada para apoyar cualquier método en el elemento como la base para obtener la clave:

 import re from operator import itemgetter def sorted_nicely(l, key): """ Sort the given iterable in the way that humans expect.""" convert = lambda text: int(text) if text.isdigit() else text alphanum_key = lambda item: [ convert(c) for c in re.split('([0-9]+)', key(item)) ] return sorted(l, key = alphanum_key) print sorted_nicely([('b10', 0), ('0', 1), ('b9', 2)], itemgetter(0)) 

Esto es exactamente lo mismo que esa respuesta, excepto generalizado para usar cualquier opción de llamada como operación en el artículo. Si solo quisiera hacerlo en una cadena, usaría lambda item: item , si quisiera hacerlo en una lista, tupla, dict o set, usaría operator.itemgetter(key_or_index_you_want) , o si quería hacerlo en una instancia de clase que podría usar operator.attrgetter('attribute_name_you_want') .

Da

 [('0', 1), ('b9', 2), ('b10', 0)] 

para su ejemplo # 2.

Las tuplas están ordenadas por defecto por sus elementos, comenzando por el primero. Así que simplemente hazlo

 L = [('b', 0), ('0', 1), ('a', 2)] L.sort() print L # or create a new, sorted list print sorted([('b', 0), ('0', 1), ('a', 2)]) 

La pregunta que le gustó habla sobre la clasificación natural, que es diferente de la clasificación normal (alfanumérica).

Digamos que quiere hacer una clasificación natural solo en el primer elemento:

 import re def naturalize(item): # turn 'b10' into ('b',10) which sorts correctly m = re.match(r'(\w+?)(\d+)', item) return m.groups() # now sort by using this function on the first element of the tuple: print sorted(L, key=lambda tup: naturalize(tup[0])) 

Como han señalado otros, ordenados usarán el primer elemento de la tupla de forma predeterminada. Si desea modificar este comportamiento predeterminado, puede especificar una clave que se utilizará durante las comparaciones.

 sorted([('b', 0), ('0', 1), ('a', 2)]) 

Devolverá lo mismo que:

 sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[0]) 

Para ordenar por el segundo elemento sin embargo intente:

 sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[1]) 

El módulo natsort hace esto por defecto sin ningún trabajo extra

 >>> from natsort import natsorted >>> natsorted([('b', 0), ('0', 1), ('a', 2)]) [('0', 1), ('a', 2), ('b', 0)] >>> natsorted([('b10', 0), ('0', 1), ('b9', 2)]) [('0', 1), ('b9', 2), ('b10', 0)]