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


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.