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

Posted

技术标签:

【中文标题】如何替换python列表特定索引处的值?【英文标题】:How to replace values at specific indexes of a python list? 【发布时间】:2011-11-06 01:39:08 【问题描述】:

如果我有一个清单:

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 吗?

【问题讨论】:

您提到的循环解决方案有什么问题(我能看到的唯一问题是l 包含 m 范围之外的索引)?您能否为这个问题提供更多背景信息? @dbr:我认为他想用 m 中的值替换由 l 中的索引索引的 s 中的值,所以这里的越界没有问题。 它包含超出 a 范围的索引,因为您正在访问 a[index],这不好。 @steabert:很好,我没有看到,因为我看不到所有 1 字母变量。 “Python 的切片对象”与这里提出的问题无关。 【参考方案1】:

你可以用字典来解决它

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]

【讨论】:

你可以用dic = dict(zip(indexes, replacements))替换第一个for循环。【参考方案2】:

您的代码最大的问题是它不可读。 Python 代码规则第一,如果它不可读,没有人会看它足够长的时间来从中获取任何有用的信息。始终使用描述性变量名称。差点没抓到你代码的bug,用好名字,慢动作回放风格再看一遍:

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 循环。

【讨论】:

是的,我更喜欢 zip-way,但我会使用 i,rep 作为运行值(我不喜欢一个字母的区别,但有时也使用它)。所以,我猜是 array 还是 zip 取决于情况。 是的,我也使用这样的缩短变量名,尤其是作为迭代中的值;我只是想强调,如果清晰很重要,使用一个完整的词并不可耻。 python 之禅说,“可读性很重要”。 添加到机器向往的评论...Zen of python - see pep 20.【参考方案3】:

为什么不只是:

map(s.__setitem__, a, m)

【讨论】:

+1 相当优雅,但并不漂亮,也不是主流。很高兴看到这个来得这么晚。 很好,但是你仍然只有一个迭代器;) @steabert:是的,但是你不使用这个函数的结果很聪明;它有点违反了没有副作用的函数式编程原则,这很讽刺,因为map本身就是python函数式编程范式的一部分。 @machine 向往:感谢您的建议。我从未考虑过map 的副作用。有时我只是把它当作 Array.forEach 的等价物,它没有 Python 实现。 @eph: 是的,如果你不知道的话,副作用只是一个用于函数所做的不涉及返回值的事情......所以即使是像输入这样的事情/output 总是基于副作用。不一定是坏事,这只是函数式编程en.wikipedia.org/wiki/Functional_programming 范式的一部分,尽量避免它们;你的函数所做的任何事情都应该在它的返回值中被捕获。 :)【参考方案4】:

对于a中的索引:

这将导致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】:

有点慢,但我认为可读:

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

【讨论】:

【参考方案6】:

您可以使用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]

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

【讨论】:

不可读,因为你又使用了无用的变量名,哈哈!这是 Python,不是 Haskell【参考方案7】:

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

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

【讨论】:

+1 哈哈,太好了,我刚把这个添加到我的帖子中,GJ。但我会争论这是否有必要。 好吧,一切都是有争议的,即使是短变量名还是长变量名,因为有时短变量名是可以的(如果在小函数中有意义的话)。至于 numpy 解决方案:对我来说,它更具可读性,并且对于大型数组,您正在使用 C 的强大功能:) 但是是的,只有在您从一开始就使用数组时才真正有用,因为将列表转换为数组需要时间。 我完全同意,这将取决于他首先为什么要这样做......但是如果他甚至没有真正使用数字数组,并且他有一个字典列表或像这样时髦的东西?想都别想。他的问题显然没有明确说明。 大声笑,我想我们被骗了...请参阅@eph 解决方案。

以上是关于如何替换python列表特定索引处的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 中的变量删除列表中特定索引处的元素? [复制]

如何将特定索引处的列表数据发送到颤动中另一个列表的特定索引

替换字符串中特定索引处的字符?

从特定索引处的列表中检索值

从现有列表中特定索引处的元素创建新列表

Java ArrayList 在特定索引处替换