Przenieść element na listę?

104

Jak w Pythonie przenieść element do określonego indeksu na liście?

Gabriele Cirulli
źródło

Odpowiedzi:

160

Użyj insertmetody listy:

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

Alternatywnie możesz użyć notacji plasterków:

l[index:index] = [item]

Jeśli chcesz przenieść element, który jest już na liście do określonej pozycji, musisz go usunąć i wstawić w nowym miejscu:

l.insert(newindex, l.pop(oldindex))
David Z
źródło
22
Pamiętaj tylko, że przeniesienie elementu znajdującego się już na liście za pomocą metody insert / pop będzie miało różne zachowanie w zależności od tego, czy przesuwasz się w przód czy w tył listy. Przechodząc w lewo wstawiasz przed wybranym obiektem. Przechodząc do tyłu wstawiasz po wybranym elemencie. Sprawdź, czy nie nastąpiło przejście na koniec listy (błąd indeksu).
MKaras
Jak przenieść wiele elementów? Biorąc pod uwagę listę a = [1,2,3,4,5,6,7,8,9], jak przekształcić ją w [1,2, [3,4,5], 6,7,8,9 ]? Czy można to zrobić w jednym kroku lub ze zrozumieniem listy?
g33kz0r
@MKaras Przetestowałem to w Pythonie 3.5 i MOŻESZ wstawiać last index + 1bez błędów. W takim przypadku element jest po prostu dodawany do listy.
user2061057
@ user2061057 jest poprawne :) nawet duże indeksy spowodują wstawienie rzeczy na końcu. a.insert(99999, 1) In [14]: a Out[14]: [...., 1]
lee penkman
1
Dla tych, którzy próbują użyć indeksu -1, aby wstawić element na końcu, musisz zamiast tego użyć len (l).
nda
32

Nieco krótsze rozwiązanie, które tylko przenosi element na koniec, nigdzie nie jest to:

l += [l.pop(0)]

Na przykład:

>>> l = [1,2,3,4,5]
>>> l += [l.pop(0)]
>>> l
[2, 3, 4, 5, 1]
Tim
źródło
13
Równie dobrze możesz użyć l.append(l.pop(0)). Jest tylko nieznacznie dłuższy, ale jest znacznie bardziej czytelny.
coredumperror
Jak mogę zamiast tego przenieść go na początek?
19

Jeśli nie znasz pozycji elementu, może być konieczne znalezienie najpierw indeksu:

old_index = list1.index(item)

następnie przesuń go:

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

lub IMHO czystszy sposób:

try:
  list1.remove(item)
  list1.insert(new_index, item)
except ValueError:
  pass
nngeek
źródło
6
Myślę, że mam rację wzdrygając się z powodu twojego passoświadczenia ... nigdy nie ukrywaj wyjątków - domyślną rzeczą w takim przykładzie powinno być podanie bardziej przejrzystego komunikatu błędu lub wypisania instrukcji ... raise ValueError(f'Unable to move item to {new_index}')lub print(f'Moving item to {new_index} failed. List remains unchanged.'). Może passbyłoby w porządku, gdyby funkcja została wywołana try_to_move_itemlub coś, co zrozumiałoby, że operacja może się nie powieść po cichu.
flutefreak7
3

Rozwiązanie bardzo proste, ale musisz znać indeks pierwotnej pozycji i indeks nowej pozycji:

list1[index1],list1[index2]=list1[index2],list1[index1]
V.Petretto
źródło
6
To jest zamiana, a nie ruch.
juzzlin
0

Wyprofilowałem kilka metod przenoszenia elementu na tej samej liście z czasem. Oto te, których należy użyć, jeśli 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)) │
└──────────┴──────────────────────┘

a tutaj te, których należy użyć, jeśli j <= i:

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

Nie jest to duża różnica, jeśli używasz go tylko kilka razy, ale jeśli robisz ciężkie rzeczy, takie jak ręczne sortowanie, ważne jest, aby wybrać najszybszy. W przeciwnym razie radziłbym po prostu wziąć ten, który uważasz za najbardziej czytelny.

Riedler Musics
źródło