Como posso reordenar uma lista? [fechadas]

107

Se eu tiver uma lista, [a,b,c,d,e]como posso reordenar os itens de maneira arbitrária, como [d,c,a,b,e]?

Edit: Eu não quero embaralhá-los. Quero reordená-los de uma maneira predefinida. (por exemplo, eu sei que o terceiro elemento da lista antiga deve se tornar o primeiro elemento da nova lista)

Niyaz
fonte
Provavelmente duplicado de stackoverflow.com/questions/976882/…
kgiannakakis
4
Sem especificar como você deseja solicitar os itens, é difícil responder. Você quer classificá-los? Embaralhá-los? Remover alguns deles?
Mizipzor 01 de
@tvanfosson: Neste caso, arbitrário também pode significar: tomar uma função de classificação arbitrária (mas bem definida).
Felix Kling
1
@mizipzor Eu quero reordená-los de uma forma predefinida. (Editou a pergunta para esclarecer isso)
Niyaz
@SilentGhost Terá um novo índice. Pode ser 4. A questão é que conheço a nova ordem dos itens.
Niyaz

Respostas:

226

Você pode fazer assim

mylist = ['a', 'b', 'c', 'd', 'e']
myorder = [3, 2, 0, 1, 4]
mylist = [mylist[i] for i in myorder]
print(mylist)         # prints: ['d', 'c', 'a', 'b', 'e']
AJ.
fonte
Isso cria uma nova variável. Como reordenar uma lista no local? Obrigado
Confundido em
@Confounded Simplesmente altere a linha final para:mylist[:] = [mylist[i] for i in myorder]
Adam,
13
>>> a = [1, 2, 3]
>>> a[0], a[2] = a[2], a[0]
>>> a
[3, 2, 1]
SilentGhost
fonte
1
Eu simplesmente não conseguia entender a sintaxe até que percebi que é uma atribuição simultânea de pares . ´ :-)
amado.por.Jesus
11
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]
Marca
fonte
@ wenlibin02, acabei de executá-lo em 2.7.5 e ainda funciona bem. Você recebe algum tipo de erro?
Marcar
sem erro, eu apenas digito: 1) import random; x = [1, 2, 3]; random.shuffle (x); #it ​​retorna None; e 2) tentei np.random.shuffle. os resultados são os mesmos.
Libin Wen de
Oh, desculpe! Não percebi que alterei diretamente o valor de x. Ele retornou Nenhum. E funciona. Obrigado.
Libin Wen de
6

A ordem final é definida por uma lista de índices?

>>> items = [1, None, "chicken", int]
>>> order = [3, 0, 1, 2]

>>> ordered_list = [items[i] for i in order]
>>> ordered_list
[<type 'int'>, 1, None, 'chicken']

editar: meh. AJ foi mais rápido ... Como posso reordenar uma lista em python?

Raphaël Saint-Pierre
fonte
3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']
ghostdog74
fonte
2

Você pode fornecer sua própria função de classificação para list.sort():

O método sort () aceita argumentos opcionais para controlar as comparações.

  • cmp especifica uma função de comparação personalizada de dois argumentos (itens de lista) que deve retornar um negativo, zero ou número positivo, dependendo se o primeiro argumento é considerado menor do que, igual ou maior do que o segundo argumento: cmp=lambda x,y: cmp(x.lower(), y.lower()). O valor padrão é None.

  • -chave especifica uma função de um argumento de que é usada para extrair uma chave de comparação a partir de cada elemento da lista: key=str.lower. O valor padrão é None.

  • reverso é um valor booleano. Se definido como True, os elementos da lista são classificados como se cada comparação fosse revertida.

Em geral, a chave e os processos de conversão reversa são muito mais rápidos do que especificar uma função cmp equivalente. Isso ocorre porque cmp é chamado várias vezes para cada elemento da lista, enquanto a tecla e o reverso tocam cada elemento apenas uma vez.

Felix Kling
fonte
2
e como exatamente você implementaria isso?
SilentGhost 01 de
@SilentGhost: Essa é uma resposta geral. No caso de OPs, sua resposta é mais apropriada. Mesmo assim, acho importante saber que existe uma solução genérica.
Felix Kling
2

Se você usar o numpy, há uma maneira legal de fazer isso:

items = np.array(["a","b","c","d"])
indices = np.arange(items.shape[0])
np.random.shuffle(indices)
print(indices)
print(items[indices])

Este código retorna:

[1 3 2 0]
['b' 'd' 'c' 'a']
user2228129
fonte
1
OP está procurando um reordenamento específico, não um embaralhamento genérico.
Teepeemm
2

Se você não se preocupa tanto com a eficiência, pode contar com a indexação de array do numpy para torná-lo elegante:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )
Shaohua Li
fonte
1

Pelo que entendi da sua pergunta, parece que você deseja aplicar uma permutação especificada em a list. Isso é feito especificando outro list(vamos chamá-lo p) que contém os índices dos elementos do original listque deveriam aparecer no permutado list. Você então usa ppara fazer um novo listsimplesmente substituindo o elemento em cada posição por aquele cujo índice está nessa posição em p.

def apply_permutation(lst, p):
    return [lst[x] for x in p]

arr=list("abcde")
new_order=[3,2,0,1,4]

print apply_permutation(arr,new_order)

Isto imprime ['d', 'c', 'a', 'b', 'e'] .

Na verdade, isso cria um novo list, mas pode ser modificado trivialmente para permutar o original "no lugar".

MAK
fonte
1

Mais uma coisa que pode ser considerada é a outra interpretação apontada por darkless

Código em Python 2.7

Principalmente:

  1. Reordenar por valor - Já resolvido por AJ acima
  2. Reordenar por índice

    mylist = ['a', 'b', 'c', 'd', 'e']
    myorder = [3, 2, 0, 1, 4]
    
    mylist = sorted(zip(mylist, myorder), key=lambda x: x[1])
    print [item[0] for item in mylist]

Isso imprimirá ['c', 'd', 'b', 'a', 'e']

Kshitij Satpute
fonte
0
newList = [oldList[3]]
newList.extend(oldList[:3])
newList.extend(oldList[4:])
inspectorG4dget
fonte
-1

Foi o que usei quando me deparei com esse problema.

def order(list_item, i): # reorder at index i
    order_at = list_item.index(i)
    ordered_list = list_item[order_at:] + list_item[:order_at]
    return ordered_list

EX: para as letras minúsculas

order(string.ascii_lowercase, 'h'):
>>> 'hijklmnopqrstuvwxyzabcdefg'

Ele simplesmente muda a lista para um índice especificado

AA Ron
fonte