sorted python 3
¿Cómo funcionan operator.itemgetter y sort() en Python? (5)
Respuesta para principiantes de Python
En palabras más simples:
- La
key=
parámetro desort
requiere una función de tecla (que se aplicará para ser objetos que se ordenarán) en lugar de un único valor de clave y - eso es exactamente lo
operator.itemgetter(1)
le daráoperator.itemgetter(1)
: una función que toma el primer elemento de un objeto similar a una lista.
(Más precisamente, esos son callables , no funciones, pero esa es una diferencia que a menudo puede ignorarse).
Tengo el siguiente código:
# initialize
a = []
# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 22, "Car Dealer"])
a.append(["Mark", 66, "Retired"])
# sort the table by age
import operator
a.sort(key=operator.itemgetter(1))
# print the table
print(a)
Crea una tabla de 4x3 y luego la ordena por edad. Mi pregunta es, ¿qué hace exactamente key=operator.itemgetter(1)
? ¿La función operator.itemgetter
devuelve el valor del elemento? ¿Por qué no puedo simplemente escribir algo como key=a[x][1]
allí? ¿O puedo? ¿Cómo podría el operador imprimir un cierto valor de la forma como 3x2
que es 22
?
¿Cómo exactamente Pitón ordena la tabla? ¿Puedo ordenarlo de forma inversa?
¿Cómo puedo ordenarlo en base a dos columnas, como la primera edad, y luego, si la edad es el mismo nombre?
¿Cómo podría hacerlo sin
operator
?
Parece que estás un poco confundido acerca de todo eso.
operator
es un módulo incorporado que proporciona un conjunto de operadores convenientes. En dos palabras operator.itemgetter(n)
construye un invocable que asume un objeto iterable (por ejemplo, list, tuple, set) como entrada, y obtiene el n-ésimo elemento fuera de él.
Entonces, no puede usar key=a[x][1]
allí, porque python no tiene idea de qué es x
. En cambio, puedes usar una función lambda
( elem
es solo un nombre de variable, no hay magia allí):
a.sort(key=lambda elem: elem[1])
O simplemente una función ordinaria:
def get_second_elem(iterable):
return iterable[1]
a.sort(key=get_second_elem)
Entonces, aquí hay una nota importante: en python las funciones son ciudadanos de primera clase , por lo que puede pasarlas a otras funciones como un parámetro.
Otras preguntas:
- Sí, puede revertir la ordenación, simplemente agregue
reverse=True
:a.sort(key=..., reverse=True)
- Para ordenar por más de una columna puede usar
itemgetter
con múltiples índices:operator.itemgetter(1,2)
, o con lambda:lambda elem: (elem[1], elem[2])
. De esta manera, los iterables se construyen sobre la marcha para cada elemento en la lista, que se comparan entre sí en orden lexicográfico (?) (Primeros elementos comparados, si son iguales, se comparan los segundos elementos, etc.) - Puede obtener el valor en [3,2] usando
a[2,1]
(los índices están basados en cero). Usando el operador ... Es posible, pero no tan limpio como solo indexar.
Consulte la documentación para más detalles:
Usted está haciendo muchas preguntas que podría responderse leyendo la documentación , por lo que le daré un consejo general: léalo y experimente en el shell de Python. Verás que itemgetter
devuelve un invocable:
>>> func = operator.itemgetter(1)
>>> func(a)
[''Paul'', 22, ''Car Dealer'']
>>> func(a[0])
8
Para hacerlo de otra manera, puedes usar lambda
:
a.sort(key=lambda x: x[1])
Y revertirlo:
a.sort(key=operator.itemgetter(1), reverse=True)
Ordenar por más de una columna:
a.sort(key=operator.itemgetter(1,2))
Vea el Cómo ordenar .
#sorting first by age then profession,you can change it in function "fun".
a = []
def fun(v):
return (v[1],v[2])
# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
a.sort(key=fun)
print a
a = []
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
print a
[[''Nick'', 30, ''Doctor''], [''John'', 8, ''Student''], [''Paul'', 8, ''Car Dealer''], [''Mark'', 66, ''Retired'']]
def _cmp(a,b):
if a[1]<b[1]:
return -1
elif a[1]>b[1]:
return 1
else:
return 0
sorted(a,cmp=_cmp)
[[''John'', 8, ''Student''], [''Paul'', 8, ''Car Dealer''], [''Nick'', 30, ''Doctor''], [''Mark'', 66, ''Retired'']]
def _key(list_ele):
return list_ele[1]
sorted(a,key=_key)
[[''John'', 8, ''Student''], [''Paul'', 8, ''Car Dealer''], [''Nick'', 30, ''Doctor''], [''Mark'', 66, ''Retired'']]
>>>