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.