Mover um item dentro de uma lista?

104

Em Python, como faço para mover um item para um índice definido em uma lista?

Gabriele Cirulli
fonte

Respostas:

160

Use o insertmétodo de uma lista:

l = list(...)
l.insert(index, item)

Como alternativa, você pode usar uma notação de fatia:

l[index:index] = [item]

Se você quiser mover um item que já está na lista para a posição especificada, deverá excluí-lo e inseri-lo na nova posição:

l.insert(newindex, l.pop(oldindex))
David Z
fonte
22
Apenas tenha em mente que mover um item que já está em uma lista com o método insert / pop terá um comportamento diferente, dependendo se você estiver movendo para a frente ou para trás da lista. Movendo para a esquerda você insere antes do objeto que você escolheu. Movendo-se para a parte traseira você insere após o item que você escolheu. Verifique se foi para o final da lista (erro de índice).
MKaras
Como mover vários elementos? Dada uma lista a = [1,2,3,4,5,6,7,8,9], como transformá-la em [1,2, [3,4,5], 6,7,8,9 ]? Isso pode ser feito em uma etapa ou com uma compreensão de lista?
g33kz0r
@MKaras eu testei isso com Python 3.5 e você PODE inserir last index + 1sem erros. O elemento é apenas anexado à lista nesse caso.
user2061057
@ user2061057 está correto :) até mesmo índices grandes resultarão em itens inseridos no final. a.insert(99999, 1) In [14]: a Out[14]: [...., 1]
Lee Penkman
1
Para aqueles que estão tentando usar o índice -1 para inserir o item no final, você deve usar len (l).
nda
31

Uma solução um pouco mais curta, que apenas move o item até o fim, não a lugar nenhum, é esta:

l += [l.pop(0)]

Por exemplo:

>>> l = [1,2,3,4,5]
>>> l += [l.pop(0)]
>>> l
[2, 3, 4, 5, 1]
Tim
fonte
13
Você também pode usar l.append(l.pop(0)). É apenas um pouco mais longo, mas é muito mais legível.
coredumperror
Como posso movê-lo para o início?
19

Se você não sabe a posição do item, pode precisar encontrar o índice primeiro:

old_index = list1.index(item)

então mova-o:

list1.insert(new_index, list1.pop(old_index))

ou IMHO de uma forma mais limpa:

try:
  list1.remove(item)
  list1.insert(new_index, item)
except ValueError:
  pass
nngeek
fonte
6
Acho que estou certo em me encolher com sua passdeclaração ... nunca esconda exceções - o padrão em um exemplo como este deve ser fornecer uma declaração de erro mais limpa ou uma declaração de impressão ... raise ValueError(f'Unable to move item to {new_index}')ou print(f'Moving item to {new_index} failed. List remains unchanged.'). Talvez passficasse ok se em uma função chamada try_to_move_itemou algo assim se entendesse que a operação pode falhar silenciosamente.
flutefreak7
3

Uma solução muito simples, mas você tem que saber o índice da posição original e o índice da nova posição:

list1[index1],list1[index2]=list1[index2],list1[index1]
V.Petretto
fonte
6
Esta é uma troca, não um movimento.
juzzlin
0

Fiz o perfil de alguns métodos para mover um item da mesma lista com o timeit. Aqui estão aqueles a serem usados ​​se j> i:

┌────────────┬────────────────────────
│ 14,4usec │ x [i: i] = x.pop (j), │
│ 14,5usec │ x [i: i] = [x.pop (j)] │
│ 15,2usec │ x.insert (i, x.pop (j)) │
└────────────┴────────────────────────

e aqui aqueles a serem usados ​​se j <= i:

┌────────────┬─────────────────────────────
│ 14,4usec │ x [i: i] = x [j] ,; del x [j] │
│ 14,4usec │ x [i: i] = [x [j]]; del x [j] │
│ 15,4usec │ x.inserir (i, x [j]); del x [j] │
└────────────┴─────────────────────────────

Não é uma grande diferença se você usá-lo apenas algumas vezes, mas se você fizer coisas pesadas como classificação manual, é importante escolher o mais rápido. Caso contrário, recomendo apenas pegar aquele que você achar mais legível.

Músicas de Riedler
fonte