Eu tenho a seguinte lista criada a partir de um CSV classificado
list1 = sorted(csv1, key=operator.itemgetter(1))
Na verdade, eu gostaria de classificar a lista por dois critérios: primeiro pelo valor no campo 1 e depois pelo valor no campo 2. Como faço isso?
__lt__()
método em sua classe ou herdar de alguma classe que faz" ? Isso tornaria um canônico muito melhor.Respostas:
como isso:
fonte
operator
é um módulo que precisa ser importado.Não há necessidade de importar nada ao usar funções lambda.
O seguinte classifica
list
pelo primeiro elemento e depois pelo segundo elemento.fonte
-
in-x[1]
?O Python tem uma classificação estável, portanto, desde que o desempenho não seja um problema, a maneira mais simples é classificá-lo pelo campo 2 e depois classificá-lo novamente pelo campo 1.
Isso fornecerá o resultado desejado, o único problema é que, se for uma lista grande (ou você quiser classificá-la com frequência), chamar a classificação duas vezes poderá ser uma sobrecarga inaceitável.
Fazer dessa maneira também facilita lidar com a situação em que você deseja que algumas das colunas sejam classificadas inversamente, basta incluir o parâmetro 'reverse = True' quando necessário.
Caso contrário, você pode passar vários parâmetros para o itemgetter ou criar manualmente uma tupla. Provavelmente será mais rápido, mas tem o problema de não generalizar bem se algumas das colunas quiserem ser classificadas inversamente (as colunas numéricas ainda podem ser revertidas negando-as, mas isso impede que a classificação seja estável).
Portanto, se você não precisar de nenhuma coluna classificada inversamente, vá para vários argumentos para itemgetter, se precisar, e as colunas não são numéricas ou você deseja manter a classificação estável por várias classificações consecutivas.
Editar: para os comentadores que têm problemas para entender como isso responde à pergunta original, aqui está um exemplo que mostra exatamente como a natureza estável da classificação garante que podemos fazer classificações separadas em cada chave e terminar com os dados classificados em vários critérios:
Este é um exemplo executável, mas para salvar as pessoas que o executam, a saída é:
Observe em particular como, no segundo passo, o
reverse=True
parâmetro mantém os primeiros nomes em ordem, enquanto a simples classificação e a reversão da lista perderiam a ordem desejada para a terceira chave de classificação.fonte
fonte
tuple()
pode receber dois argumentos (ou melhor, três, se contarmos comself
)return
declaração deve serreturn tuple((x[1], x[2]))
ou simplesmentereturn x[1], x[2]
. Consulte @jaap resposta abaixo se você está procurando para a classificação em diferentes direçõestuple(x[1:3])
, se você quiser usar o construtor de tupla por algum motivo, em vez de apenas uma lista de exibição de tuplax[1], x[2]
. Oukeyfunc = operator.itemgetter(1, 2)
e nem mesmo escreva uma função.Também podemos usar .sort com lambda 2 vezes, porque a classificação python está no lugar e é estável. Isso primeiro classificará a lista de acordo com o segundo elemento, x [1]. Em seguida, ele classificará o primeiro elemento, x [0] (prioridade mais alta).
Isso é equivalente ao seguinte: employee.sort (key = lambda x: (x [0], x [1]))
fonte
Em ordem crescente, você pode usar:
ou em ordem decrescente, você pode usar:
fonte
A lista de classificação dos dictos usando abaixo classificará a lista em ordem decrescente na primeira coluna como salário e na segunda coluna como idade
Resultado: [{'salário': 123, 'idade': 25}, {'salário': 123, 'idade': 23}]
fonte