如何替换python列表的特定索引的值?

时间:2011-08-29 14:04:36

标签: python arrays slice

如果我有一个清单:

to_modify = [5,4,3,2,1,0]

然后宣布另外两个名单:

indexes = [0,1,3,5]
replacements = [0,0,0,0]

如何将to_modify的元素作为indexes的索引,然后将to_modify中的相应元素设置为replacements,即在运行后indexes应该是[0,0,3,0,1,0]

显然,我可以通过for循环来做到这一点:

for ind in to_modify:
    indexes[to_modify[ind]] = replacements[ind]

但还有其他办法吗? 我可以用某种方式使用operator.itemgetter吗?

7 个答案:

答案 0 :(得分:28)

您的代码最大的问题是它无法读取。 Python代码规则第一,如果它不可读,没有人会长时间地查看它以从中获取任何有用的信息。始终使用描述性变量名称。几乎没有捕到你的代码中的错误,让我们再次看到它的好名字,慢动作重播风格:

to_modify = [5,4,3,2,1,0]
indexes = [0,1,3,5]
replacements = [0,0,0,0]

for index in indexes:
    to_modify[indexes[index]] = replacements[index]
    # to_modify[indexes[index]]
    # indexes[index]
    # Yo dawg, I heard you liked indexes, so I put an index inside your indexes
    # so you can go out of bounds while you go out of bounds.

当您使用描述性变量名时很明显,您使用自身的值索引索引列表,在这种情况下没有意义。

同样,当并行迭代2个列表时,我喜欢使用zip函数(或izip如果你担心内存消耗,但我不是那些迭代纯粹主义者之一)。所以试试吧。

for (index, replacement) in zip(indexes, replacements):
    to_modify[index] = replacement

如果您的问题只与数字列表一起使用,那么我会说@steabert有你正在寻找的那些numpy的答案。但是,您不能将序列或其他可变大小的数据类型用作numpy数组的元素,因此如果您的变量to_modify中有类似的内容,那么您最好使用for循环进行此操作。< / p>

答案 1 :(得分:17)

numpy具有允许您使用其他列表/数组作为索引的数组:

import numpy
S=numpy.array(s)
S[a]=m

答案 2 :(得分:6)

为什么不呢:

map(s.__setitem__, a, m)

答案 3 :(得分:2)

有点慢,但我认为可读:

>>> s, l, m
([5, 4, 3, 2, 1, 0], [0, 1, 3, 5], [0, 0, 0, 0])
>>> d = dict(zip(l, m))
>>> d  #dict is better then using two list i think
{0: 0, 1: 0, 3: 0, 5: 0}
>>> [d.get(i, j) for i, j in enumerate(s)]
[0, 0, 3, 0, 1, 0]

答案 4 :(得分:1)

  

表示索引:

这会导致index采用a元素的值,因此将它们用作索引并不是您想要的。在Python中,我们通过实际迭代来迭代容器。

“但等等”,你说,“对于a中的每一个元素,我需要使用m的相应元素。如果没有索引,我该怎么做呢?”

简单。我们将am转换为对的列表(来自a的元素,来自m的元素),并迭代对。这很容易 - 只需使用内置库函数zip,如下所示:

for a_element, m_element in zip(a, m):
  s[a_element] = m_element

为了使其按照您尝试的方式工作,您必须获取要迭代的索引列表。这是可行的:例如,我们可以使用range(len(a))。但是不要那样做!这不是我们用Python做事的方式。实际上,直接迭代你想要迭代的东西是一个美丽的,解放思想的想法。

  

operator.itemgetter

怎么样?

这里不太相关。 operator.itemgetter的目的是将索引的行为转换为类似函数的东西(我们称之为“可调用的”),以便它可以用作回调(例如,'键' '用于排序或最小/最大操作)。如果我们在这里使用它,我们必须每次通过循环重新调用它来创建一个新的itemgetter,这样我们就可以立即使用它并抛弃它。在上下文中,这只是忙碌的工作。

答案 5 :(得分:0)

您可以使用operator.setitem

from operator import setitem
a = [5, 4, 3, 2, 1, 0]
ell = [0, 1, 3, 5]
m = [0, 0, 0, 0]
for b, c in zip(ell, m):
    setitem(a, b, c)
>>> a
[0, 0, 3, 0, 1, 0]

它比您的解决方案更具可读性或效率吗?我不确定!

答案 6 :(得分:0)

您可以使用字典来解决

to_modify = [5,4,3,2,1,0]
indexes = [0,1,3,5]
replacements = [0,0,0,0]

dic = {}
for i in range(len(indexes)):
    dic[indexes[i]]=replacements[i]
print(dic)

for index, item in enumerate(to_modify):
    for i in indexes:
        to_modify[i]=dic[i]
print(to_modify)

输出将为

{0: 0, 1: 0, 3: 0, 5: 0}
[0, 0, 3, 0, 1, 0]