Python 更改列表的指定索引的最佳方法
我想立即替换列表中的某些元素 假设我们有以下列表:Python 更改列表的指定索引的最佳方法,python,Python,我想立即替换列表中的某些元素 假设我们有以下列表: list = [1, 2, 3, 4, 5, 6] idx = [1, 3, 4] new = [100, 200, 300] 我想用新值替换列表中的元素1、3、4。例如: list[idx] = new 最后的列表是=>[1100,3200,300,6] 我知道你可以在Matlab中以这种方式使用它,但是想知道我在Python中应该做什么吗 注意:我知道可以使用循环并执行此操作 编辑:我想使用纯python解决方案 L = [1, 2,
list = [1, 2, 3, 4, 5, 6]
idx = [1, 3, 4]
new = [100, 200, 300]
我想用新值替换列表中的元素1、3、4。例如:
list[idx] = new
最后的列表是=>[1100,3200,300,6]
我知道你可以在Matlab中以这种方式使用它,但是想知道我在Python中应该做什么吗
注意:我知道可以使用循环并执行此操作
编辑:我想使用纯python解决方案
L = [1, 2, 3, 4, 5, 6]
idx = [1, 3, 4]
new = [100, 200, 300]
for i in range(len(idx)):
L[idx[i]] = new[i]
没有循环的稍慢版本:
L = [1, 2, 3, 4, 5, 6]
idx = [1, 3, 4]
new = [100, 200, 300]
L = [num if i not in idx else new[i] for i,num in enumerate(L)]
python的方法是使用zip:
Python本身不支持matlab风格的数组操作,但如果您对这种编码风格感兴趣,可以研究numpy,请参见@abarnert的答案 既然您正在寻找类似Matlab的解决方案,那么您很有可能真的应该在这里使用。事实上,如果您这样做,就可以完全按照您的要求编写代码:
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> idx = [1, 3, 4]
>>> new = [100, 200, 300]
>>> a[idx] = new
>>> a
array([ 1, 100, 3, 200, 300, 6])
除了为您提供Matlab-ish元素级操作符和函数外,NumPy还为您提供了方便的多维数组,以及访问大量高级函数库的权限,特别是如果您包括类似的附加库的话。另外,您通常会获得性能优势,例如6倍的速度和0.25倍的空间
如果您想要一个纯Python解决方案,那么在Python中实现这么多NumPy或者您需要的那么多并不难。您可以用任何方式编写自己的数组类。特别要注意的是,a[idx]=new调用a.。\uuuu setitem\uuuu idx,new。您可能希望以与list相同的方式处理单个数字和切片,但没有任何东西可以阻止您处理list拒绝的其他类型。例如:
def __setitem__(self, idx, value):
if isinstance(idx, collections.abc.Iterable):
for i, v in zip(idx, value):
self.lst[i] = v
else:
self.lst[idx] = value
对于idx和value具有不同长度的情况,您可能需要添加一些错误处理。你可以从第一原则中找出最好的规则,或者从看NumPy做什么开始,然后决定你做什么和不想复制什么
当然,这一实现的核心代码与alexis的答案非常相似并不是偶然的,因为我们所做的只是包装逻辑,所以您只需编写一次,而不是每次需要时编写一次。首先,为什么要使用rangelenidx而不是zipidx,new?另外,第二个版本与第一个版本有相同的循环,是什么让你觉得它更慢?@abarnert:第二个版本在列表中查找元素,这需要时间;因此,经济放缓。zip绝对是比我的第一个loopAh更好的版本,我没有看到你这样做;是的,比较慢。但是你可以很容易地编写一个listcomp,它可能会更快,除了像这样的非常小的输入,它可能会更慢,但谁在乎呢?。我可能过于谨慎了,因为有太多的答案错误地暗示,对列表进行适当的修改通常比构建一个新的列表要快,因为这在C语言中是正确的,而在Python中通常是错误的,甚至更不相关;为没有更仔细地阅读而道歉。或者根本不改变现有的列表;类似于d=dictzipidx的东西,新的;L=[d.getidx,idx的值,enumerateL中的值]。在许多情况下,新列表更合适,但问题是更新列表。当然,但通常最好的方法是使用新列表,然后使用L=或L[:]=…在这种情况下,这可能是真的,也可能不是真的,但是对于新手来说,了解这两种方法是值得的,这样他们就可以选择正确的方法。我同意。不过,在这种情况下,更新非常简单,如果需要一个新列表,我会先复制一个副本,然后将编辑应用到副本上。Numpy是一个很好的库,我以前使用过它。但是我想要一个纯python的解决方案:@mehD:好吧,你可以用纯python编写这么多的NumPy;事实上,这很琐碎。请参阅我的最新答案。
def __setitem__(self, idx, value):
if isinstance(idx, collections.abc.Iterable):
for i, v in zip(idx, value):
self.lst[i] = v
else:
self.lst[idx] = value