Insérer un élément à un index spécifique dans une liste et renvoyer la liste mise à jour


99

J'ai ceci:

>>> 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]

Existe-t-il un moyen d'obtenir la liste mise à jour comme résultat, au lieu de mettre à jour la liste d'origine en place?


11
b = a[:].insert(2,3)semble assez court, n'affecte pas la liste originale et est assez descriptif.
— mkoistinen le

6
@mkoistinen Cela ne fonctionne pas pour moi. >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
— SparkAndShine

Réponses:


89

l.insert(index, obj)ne renvoie rien. Il met simplement à jour la liste.

Comme l'a dit ATO, vous pouvez le faire b = a[:index] + [obj] + a[index:]. Cependant, une autre façon est:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)

56
Si vous ne pouvez pas tolérer 3 lignes de code lisible, mettez-le dans une fonction et appelez-le.
— IceArdor

54

Approche la plus efficace en termes de performances

Vous pouvez également insérer l'élément en utilisant l' indexation de tranche dans la liste. Par exemple:

>>> 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]

Pour insérer plusieurs éléments ensemble à un index donné , tout ce que vous avez à faire est d'utiliser un ou listplusieurs éléments que vous souhaitez insérer. Par exemple:

>>> 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]

Alternative utilisant la compréhension de liste (mais très lente en termes de performances) :

Comme alternative, cela peut être réalisé en utilisant la compréhension de liste avec enumerateaussi. (Mais veuillez ne pas le faire de cette façon. C'est juste à titre d'illustration) :

>>> 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]

Comparaison des performances de toutes les solutions

Voici la timeitcomparaison de toutes les réponses avec une liste de 1000 éléments pour Python 3.4.5:

  • Réponse à la mine par insertion tranchée - Plus rapide (3,08 µs par boucle)

     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
  • Réponse acceptée d'ATOzTOA basée sur la fusion de listes découpées - Seconde (6,71 µs par boucle)

     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
  • Réponse de Rushy Panchal avec la plupart des votes utilisantlist.insert(...)- Troisième (26,5 usec par boucle)

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec per loop
  • Ma réponse avec List Comprehension etenumerate- Quatrième (très lent avec 168 µs par boucle)

     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

2
J'aime vraiment ce résultat car il s'étend facilement pour résoudre le problème, que faire si je veux insérer les valeurs 3, 3.5dans cette liste (dans l'ordre) -> a[2:2] = [3,3.5]. Très soigné
— minillinim

1
Comment fonctionne une [2: 2] = a_list? a [2: 2] commence fondamentalement du 2e index au 1er index (2-1) mais dans le sens avant, ce qui signifie une liste [] vide. Comment ça s'étend? Si nous faisons [2: 3: -1] cela ne fonctionne pas.
— SamCodes

Très bonne réponse. Je me demande si la complexité du meilleur choix est O (1)? Si oui, pourquoi?
— Lerner Zhang le

Cette réponse doit être mise à jour. Pour une fois, je ne peux pas reproduire les timings rapportés même avec Python 3.4 (j'obtiens un facteur 2 entre list.insertet l'assignation de tranche), et sur Python 3.8 cette différence a complètement disparu. La manière la plus claire d'insérer un élément est de l'utiliser list.insert, évidemment.
— a_guest le

39

Le plus court que j'ai: 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]

Le nombre de lignes de code n'est pas une bonne mesure de la qualité du code. Cette approche est imparfaite pour des raisons de performances et de lisibilité.
— a_guest le

0

L'approche la plus propre consiste à copier la liste, puis à insérer l'objet dans la copie. Sur Python 3, cela peut être fait via list.copy:

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

Sur Python 2, la copie de la liste peut être réalisée via new = old[:](cela fonctionne également sur Python 3).

En termes de performances, il n'y a pas de différence avec les autres méthodes proposées:

$ 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

-1

Utilisez la méthode Python list insert () . Usage:

#Syntaxe

La syntaxe de la méthode insert () -

list.insert(index, obj)

#Paramètres

  • index - Il s'agit de l'index dans lequel l'objet obj doit être inséré.
  • obj - C'est l'objet à insérer dans la liste donnée.

#Return Value Cette méthode ne renvoie aucune valeur, mais insère l'élément donné à l'index donné.

Exemple:

a = [1,2,4,5]

a.insert(2,3)

print(a)

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


2
Cela ne répond pas à la question.
— Gustav Bertram

5
La question était précise: Is there anyway I can get the updated list as result, instead of updating the original list in place?votre réponse fait le contraire.
— Laszlowaty
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.