リストの特定のインデックスに要素を挿入し、更新されたリストを返す


99

私はこれを持っています:

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

とにかく元のリストを更新する代わりに、結果として更新されたリストを取得できますか?


11
b = a[:].insert(2,3)かなり短く見え、元のリストには影響せず、かなり説明的です。
mkoistinen 2014年

6
@mkoistinenそれは私にはうまくいきません。>>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine 2015年

回答:


89

l.insert(index, obj)実際には何も返さず、リストを更新するだけです。ATOが言ったように、あなたはできるb = a[:index] + [obj] + a[index:]。ただし、別の方法は次のとおりです。

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

56
3行の読み取り可能なコードを許容できない場合は、それを関数に入れて呼び出します。
IceArdor 2014

53

最も効率的なアプローチ

リストのスライスインデックスを使用して要素を挿入することもできます。例えば:

>>> 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 original list

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

以下のために指定されたインデックスで一緒に複数の要素を挿入し、すべてを行う必要が使用することですlistあなたが挿入すること、複数の要素から。例えば:

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

リスト内包表記を使用した代替方法 (ただし、パフォーマンスの点で非常に遅い)

別の方法として、リスト内包表記を使用しても実現できますenumerate(ただし、この方法で行わないでください。これは説明のためのものです)

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

すべてのソリューションのパフォーマンス比較

以下はtimeit、Python 3.4.5のすべての回答と1000要素のリストの比較です。

  • スライスされた挿入を使用した地雷の回答 -最速(ループあたり3.08 usec)

    mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b[500:500] = [3]"
    100000 loops, best of 3: 3.08 usec per loop
    
  • スライスされたリストのマージに基づく ATOzTOAの受け入れられた回答-2番目(ループあたり6.71 usec)

    mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:500] + [3] + a[500:]"
    100000 loops, best of 3: 6.71 usec per loop
    
  • Rushy Panchalのほとんどの投票での回答 -3list.insert(...)番目(ループあたり26.5 usec)

    python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
    10000 loops, best of 3: 26.5 usec per loop
    
  • 鉱山の答えリスト理解enumerate四- (ループあたり168マイクロ秒と非常に遅いです)

    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 usec per loop
    

2
問題を解決するために簡単に拡張できるので、この結果は本当に気に入っています。値3, 3.5をそのリストに(順番に)挿入したい場合はどうでしょうか-> a[2:2] = [3,3.5]。非常にきちんと
minillinim '15年

1
a [2:2] = a_listはどのように機能しますか?a [2:2]は基本的に2番目のインデックスから1番目のインデックス(2-1)まで始まりますが、順方向であるので、空の[]リストを意味します。どのように拡張しますか?[2:3:-1]を実行しても機能しません。
SamCodes 2018

すばらしい答えです。最良の選択の複雑さはO(1)なのでしょうか。もしそうなら、なぜですか?
Lerner Zhang

この回答は更新する必要があります。一応、Python 3.4でも報告されたタイミングを再現できません(list.insertスライス割り当ての間に2の因数が得られます)。Python3.8では、この違いは完全になくなりました。要素を挿入する最も明確な方法はlist.insert、明らかにを使用することです。
a_guest

39

私が得た最短: 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]

コードの行数は、コード品質の良い尺度ではありません。このアプローチは、パフォーマンスと読みやすさの両方の理由で欠点があります。
a_guest

0

最もクリーンな方法は、リストをコピーしてから、オブジェクトをコピーに挿入することです。Python 3では、これは次の方法で実行できますlist.copy

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

Python 2では、リストのコピーはnew = old[:](Python 3でも機能します)を介して実行できます。

パフォーマンスに関しては、他の提案された方法との違いはありません。

$ 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 usec per loop
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b[500:500] = (3,)"
100000 loops, best of 5: 2.76 usec per loop

-1

使用Pythonのリストの挿入()メソッドを。使用法:

構文

以下は、insert()メソッドの構文です-

list.insert(index, obj)

パラメーター

  • index-これは、オブジェクトobjを挿入する必要があるインデックスです。
  • obj-これは、指定されたリストに挿入されるオブジェクトです。

戻り値

このメソッドは値を返しませんが、指定された要素を指定されたインデックスに挿入します。

例:

a = [1,2,4,5]

a.insert(2,3)

print(a)

戻り値 [1, 2, 3, 4, 5]


1
これは質問の答えにはなりません。
グスタフベルトラム

4
質問は具体的でした:Is there anyway I can get the updated list as result, instead of updating the original list in place?あなたの答えは反対です。
Laszlowaty、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.