Python tiene una clasificación estable, por lo que siempre que el rendimiento no sea un problema, la forma más simple es ordenarlo por el campo 2 y luego ordenarlo nuevamente por el campo 1.
Eso le dará el resultado que desea, el único inconveniente es que si se trata de una lista grande (o si desea ordenarla con frecuencia) llamar a ordenar dos veces podría ser una sobrecarga inaceptable.
list1 = sorted(csv1, key=operator.itemgetter(2))
list1 = sorted(list1, key=operator.itemgetter(1))
Hacerlo de esta manera también facilita el manejo de la situación en la que desea que algunas de las columnas se ordenen de forma inversa, solo incluya el parámetro 'reverse = True' cuando sea necesario.
De lo contrario, puede pasar múltiples parámetros a itemgetter o construir manualmente una tupla. Probablemente sea más rápido, pero tiene el problema de que no se generaliza bien si algunas de las columnas quieren ser ordenadas en reversa (las columnas numéricas aún pueden revertirse negándolas pero eso impide que la ordenación sea estable).
Entonces, si no necesita ninguna columna ordenada inversamente, busque múltiples argumentos para agregar elementos, si lo desea, y las columnas no son numéricas o si desea mantener la clasificación estable, vaya a varias clasificaciones consecutivas.
Editar: Para los comentaristas que tienen problemas para entender cómo esto responde a la pregunta original, aquí hay un ejemplo que muestra exactamente cómo la naturaleza estable de la clasificación garantiza que podamos hacer clasificaciones separadas en cada clave y terminar con datos ordenados en múltiples criterios:
DATA = [
('Jones', 'Jane', 58),
('Smith', 'Anne', 30),
('Jones', 'Fred', 30),
('Smith', 'John', 60),
('Smith', 'Fred', 30),
('Jones', 'Anne', 30),
('Smith', 'Jane', 58),
('Smith', 'Twin2', 3),
('Jones', 'John', 60),
('Smith', 'Twin1', 3),
('Jones', 'Twin1', 3),
('Jones', 'Twin2', 3)
]
# Sort by Surname, Age DESCENDING, Firstname
print("Initial data in random order")
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred''')
DATA.sort(key=lambda row: row[1])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.''')
DATA.sort(key=lambda row: row[2], reverse=True)
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
''')
DATA.sort(key=lambda row: row[0])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
Este es un ejemplo ejecutable, pero para salvar a las personas que lo ejecutan, el resultado es:
Initial data in random order
Jones Jane 58
Smith Anne 30
Jones Fred 30
Smith John 60
Smith Fred 30
Jones Anne 30
Smith Jane 58
Smith Twin2 3
Jones John 60
Smith Twin1 3
Jones Twin1 3
Jones Twin2 3
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Jones Jane 58
Smith Jane 58
Smith John 60
Jones John 60
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.
Smith John 60
Jones John 60
Jones Jane 58
Smith Jane 58
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
Jones John 60
Jones Jane 58
Jones Anne 30
Jones Fred 30
Jones Twin1 3
Jones Twin2 3
Smith John 60
Smith Jane 58
Smith Anne 30
Smith Fred 30
Smith Twin1 3
Smith Twin2 3
Observe en particular cómo en el segundo paso el reverse=True
parámetro mantiene los nombres en orden, mientras que simplemente ordenar y revertir la lista perdería el orden deseado para la tercera clave de clasificación.