Wstaw element pod określonym indeksem na liście i zwróć zaktualizowaną listę

102

Mam to:

>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]

>>> print a.insert(2, 3)
None

>>> print a
[1, 2, 3, 4]

>>> b = a.insert(3, 6)
>>> print b
None

>>> print a
[1, 2, 3, 6, 4]

Czy istnieje sposób, aby uzyskać zaktualizowaną listę jako wynik zamiast aktualizowania oryginalnej listy na miejscu?

ATOzTOA
źródło
11
b = a[:].insert(2,3)wydaje się dość krótki, nie ma wpływu na oryginalną listę i jest dość opisowy.
mkoistinen
6
@mkoistinen To nie działa dla mnie. >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine

Odpowiedzi:

91

l.insert(index, obj)tak naprawdę nic nie zwraca. Po prostu aktualizuje listę.

Jak powiedział ATO, możesz to zrobić b = a[:index] + [obj] + a[index:]. Jednak inny sposób to:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)
Rushy Panchal
źródło
56
Jeśli nie możesz tolerować 3 wierszy czytelnego kodu, umieść go w funkcji i wywołaj.
IceArdor
60

Najbardziej wydajne podejście

Możesz również wstawić element za pomocą indeksowania plasterków na liście. Na przykład:

>>> a = [1, 2, 4]
>>> insert_at = 2  # Index at which you want to insert item

>>> b = a[:]   # Created copy of list "a" as "b".
               # Skip this step if you are ok with modifying the original list

>>> b[insert_at:insert_at] = [3]  # Insert "3" within "b"
>>> b
[1, 2, 3, 4]

Aby wstawić wiele elementów razem w danym indeksie , wystarczy użyć jednego listz wielu elementów, które chcesz wstawić. Na przykład:

>>> a = [1, 2, 4]
>>> insert_at = 2   # Index starting from which multiple elements will be inserted

# List of elements that you want to insert together at "index_at" (above) position
>>> insert_elements = [3, 5, 6]

>>> a[insert_at:insert_at] = insert_elements
>>> a   # [3, 5, 6] are inserted together in `a` starting at index "2"
[1, 2, 3, 5, 6, 4]

Alternatywne użycie rozumienia list (ale bardzo powolne pod względem wydajności) :

Alternatywnie można to osiągnąć za pomocą rozumienia list z enumeratezbyt. (Ale proszę, nie rób tego w ten sposób. To tylko dla ilustracji) :

>>> a = [1, 2, 4]
>>> insert_at = 2

>>> b = [y for i, x in enumerate(a) for y in ((3, x) if i == insert_at else (x, ))]
>>> b
[1, 2, 3, 4]

Porównanie wydajności wszystkich rozwiązań

Oto timeitporównanie wszystkich odpowiedzi z listą 1000 elementów dla Pythona 3.4.5:

  • Moja odpowiedź przy użyciu wstawiania w plasterkach - najszybsza (3,08 µs na pętlę)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b[500:500] = [3]"
     100000 loops, best of 3: 3.08 µsec per loop
    
  • Zaakceptowana odpowiedź ATOzTOA oparta na scalaniu list podzielonych na plasterki - druga (6,71 µsek na pętlę)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:500] + [3] + a[500:]"
     100000 loops, best of 3: 6.71 µsec per loop
    
  • Odpowiedź Rushy'ego Panchala z większością głosówlist.insert(...)- trzecia (26,5 usek na pętlę)

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec per loop
    
  • Moja odpowiedź ze zrozumieniem listy ienumerate- czwarty (bardzo wolny z 168 µs na pętlę)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "[y for i, x in enumerate(a) for y in ((3, x) if i == 500 else (x, )) ]"
     10000 loops, best of 3: 168 µsec per loop
    
Moinuddin Quadri
źródło
2
Bardzo podoba mi się ten wynik, ponieważ łatwo rozszerza się, aby rozwiązać problem, a co jeśli chcę wstawić wartości 3, 3.5do tej listy (w kolejności) -> a[2:2] = [3,3.5]. Bardzo fajnie
minillinim
1
Jak działa [2: 2] = a_list? a [2: 2] zasadniczo zaczyna się od drugiego indeksu do pierwszego indeksu (2-1), ale w kierunku do przodu, co oznacza pustą listę []. Jak to się wydłuża? Jeśli zrobimy [2: 3: -1], to nie zadziała.
SamCodes
Świetna odpowiedź. Zastanawiam się, czy złożoność najlepszego wyboru to O (1)? Jeśli tak, dlaczego?
Lerner Zhang
Ta odpowiedź wymaga aktualizacji. Po raz pierwszy nie mogę odtworzyć raportowanych czasów nawet w Pythonie 3.4 (otrzymuję współczynnik 2 między list.inserti przypisanie wycinka), aw Pythonie 3.8 ta różnica całkowicie zniknęła. Najwyraźniejszym sposobem wstawienia elementu jest list.insertoczywiście użycie .
a_guest
39

Najkrótszy, jaki uzyskałem: b = a[:2] + [3] + a[2:]

>>>
>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]
>>> b = a[:2] + [3] + a[2:]
>>> print a
[1, 2, 4]
>>> print b
[1, 2, 3, 4]
ATOzTOA
źródło
Liczba wierszy kodu nie jest dobrą miarą jakości kodu. To podejście jest wadliwe zarówno ze względu na wydajność, jak i czytelność.
a_guest
0

Najczystszym podejściem jest skopiowanie listy, a następnie wstawienie obiektu do kopii. W Pythonie 3 można to zrobić za pomocą list.copy:

new = old.copy()
new.insert(index, value)

W Pythonie 2 można skopiować listę za pomocą new = old[:](działa to również w Pythonie 3).

Pod względem wydajności nie ma różnicy w stosunku do innych proponowanych metod:

$ python --version
Python 3.8.1
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b.insert(500, 3)"
100000 loops, best of 5: 2.84 µsec per loop
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b[500:500] = (3,)"
100000 loops, best of 5: 2.76 µsec per loop
gość
źródło
-2

Użyj metody insert () listy Pythona . Stosowanie:

#Składnia

Składnia metody insert () -

list.insert(index, obj)

#Parameters

  • index - jest to indeks, do którego należy wstawić obiekt obj.
  • obj - To jest obiekt do wstawienia do podanej listy.

#Return Value Ta metoda nie zwraca żadnej wartości, ale wstawia dany element pod podanym indeksem.

Przykład:

a = [1,2,4,5]

a.insert(2,3)

print(a)

Zwroty [1, 2, 3, 4, 5]

Arjun Sanchala
źródło
2
To nie odpowiada na pytanie.
Gustav Bertram,
5
Pytanie było konkretne: Is there anyway I can get the updated list as result, instead of updating the original list in place?Twoja odpowiedź jest odwrotna.
Laszlowaty