在列表中的特定索引处插入元素,然后返回更新后的列表


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年

Answers:


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年

54

最高效的方法

您也可以使用列表中的切片索引插入元素。例如:

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

在给定索引处将多个元素一起插入,您要做的就是使用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微秒)

     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
  • ATOzTOA接受的基于切片列表合并的答案 -秒(每个循环6.71微秒)

     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
  • 鲁希·潘查尔(Rushy Panchal)的票数最多,答案list.insert(...)-第三(每个循环26.5 微秒

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec 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 µsec per loop

2
我非常喜欢这个结果,因为它很容易扩展以解决问题,如果我想将这些值3, 3.5(按顺序)插入到列表中,该怎么办a[2:2] = [3,3.5]?非常整洁
minillinim

1
a [2:2] = a_list如何工作?a [2:2]基本上从第二个索引开始到第一个索引(2-1),但是向前方向,这意味着一个空的[]列表。它如何扩展?如果我们[2:3:-1]不起作用。
SamCodes

好答案。我想知道最佳选择的复杂度是否为O(1)?如果是这样,为什么?
Lerner Zhang

该答案需要更新。一次,即使使用Python 3.4,我也无法重现报告的时序(我在list.insert切片分配之间获得2的系数),而在Python 3.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 µ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

使用Python列表insert()方法。用法:

#句法

insert()方法的语法-

list.insert(index, obj)

#参数

  • index-这是需要在其中插入对象obj的索引。
  • obj-这是要插入给定列表的对象。

#Return Value此方法不返回任何值,但会将给定元素插入给定索引。

例:

a = [1,2,4,5]

a.insert(2,3)

print(a)

退货 [1, 2, 3, 4, 5]


2
这不能回答问题。
Gustav Bertram '18年

5
问题很具体:Is there anyway I can get the updated list as result, instead of updating the original list in place?您的回答相反。
Laszlowaty
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.