在 Python 中替换列表中的选定元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14350400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Replacing selected elements in a list in Python
提问by elwc
I have a list: mylist = [0, 0, 0, 0, 0]
我有一个清单: mylist = [0, 0, 0, 0, 0]
I only want to replace selected elements, say the first, second, and fourth by a common number, A = 100.
我只想用一个公共数字A = 100.
One way to do this:
一种方法:
mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]
I am looking for a one-liner, or an easier method to do this. A more general and flexible answer is preferable.
我正在寻找一种单线或一种更简单的方法来做到这一点。更通用和更灵活的答案是可取的。
采纳答案by abarnert
Especially since you're replacing a sizable chunk of the list, I'd do this immutably:
特别是因为你要更换的一个相当大的一块list,我会做这个一成不变:
mylist = [100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)]
It's intentional in Python that making a new listis a one-liner, while mutating a listrequires an explicit loop. Usually, if you don't know which one you want, you want the new list. (In some cases it's slower or more complicated, or you've got some other code that has a reference to the same listand needs to see it mutated, or whatever, which is why that's "usually" rather than "always".)
在 Python 中有意使 newlist是单行的,而改变 alist需要显式循环。通常,如果您不知道自己想要哪个,则需要新的list. (在某些情况下它更慢或更复杂,或者你有一些其他代码引用相同的代码list并且需要看到它发生变异,或者其他什么,这就是为什么那是“通常”而不是“总是”。)
If you want to do this more than once, I'd wrap it up in a function, as Volatility suggests:
如果您想多次执行此操作,我会将其封装在一个函数中,正如 Volatility 所建议的那样:
def elements_replaced(lst, new_element, indices):
return [new_element if i in indices else e for i, e in enumerate(lst)]
I personally would probably make it a generator so it yields an iteration instead of returning a list, even if I'm never going to need that, just because I'm stupid that way. But if you actually doneed it:
我个人可能会把它变成一个生成器,所以它会产生一个迭代而不是返回一个列表,即使我永远不需要它,只是因为我那样愚蠢。但是,如果你真的这样做需要它:
myiter = (100 if i in (0, 1, 3) else e for i, e in enumerate(mylist))
Or:
或者:
def elements_replaced(lst, new_element, indices):
for i, e in enumerate(lst):
if i in indices:
yield new_element
else:
yield e
回答by Marius
Is this what you're looking for? Make a list of the indexes you want to change, and then loop through that list to change the values.
这是你要找的吗?列出要更改的索引,然后遍历该列表以更改值。
els_to_replace = [0, 1, 3]
mylist = [0, 0, 0, 0, 0]
for index in els_to_replace:
mylist[index] = 100
mylist
Out[9]: [100, 100, 0, 100, 0]
回答by Volatility
def replace_element(lst, new_element, indices):
for i in indices:
lst[i] = new_element
return lst
It's definitely a more general solution, not a one-liner though. For example, in your case, you would call:
这绝对是一个更通用的解决方案,但不是单线解决方案。例如,在你的情况下,你会打电话:
mylist = replace_element(mylist, 100, [0, 1, 3])
回答by mgilson
Numpy supports this if you're not opposed to using an np.ndarray:
如果您不反对使用 Numpy 支持np.ndarray:
>>> a = np.zeros(5)
>>> a[[0,1,3]] = 100
>>> a
array([ 100., 100., 0., 100., 0.])
回答by RocketDonkey
Not a huge fan of this one, but you could try this (although I think all of the above are much more concise and easy to read):
不是这个的忠实粉丝,但你可以试试这个(虽然我认为以上所有内容都更加简洁易读):
In [22]: from operator import setitem
In [23]: mylist = [0, 0, 0, 0, 0]
In [24]: indeces_to_replace = [0, 1, 3]
In [25]: _ = map(lambda x: setitem(mylist, x, 100), indeces_to_replace)
In [26]: mylist
Out[26]: [100, 100, 0, 100, 0]
Aside from the questionable readability and need for an import, @abarnert pointed out a few additional issues, namely that mapstill creates an unnecessary list (which is discarded with the _but created nonetheless) and that it won't work in Python 3 because mapreturns an iteratorin Python 3.x. You can use the sixmodule to simulate the behavior of mapin Python 3.x from Python 2.x, and in combination with collections.deque(again as suggested by @abarnert), you can achieve the same output without creating the additional list in memory because a dequethat can contain a maximum of 0items will discard everything it receives from the mapiterator (note that with six, mapis simulated by using itertools.imap).
除了有问题的可读性和需要导入之外,@abarnert 还指出了一些额外的问题,即map仍然会创建一个不必要的列表(它被丢弃_但仍然创建)并且它不会在 Python 3 中工作,因为map返回一个Python 3.x 中的迭代器。您可以使用六个模块map从 Python 2.x 中模拟Python 3.x 中的行为,并结合使用collections.deque(再次按照@abarnert 的建议),您可以实现相同的输出,而无需在内存中创建额外的列表,因为deque可以包含最多0项目的将丢弃它从map迭代器接收的所有内容(请注意, with six,map是通过 using 模拟的itertools.imap)。
Again, there is absolutely no need to ever use this - every solution above/below is better :)
同样,绝对没有必要使用它 - 上面/下面的每个解决方案都更好:)
In [1]: from collections import deque
In [2]: from six.moves import map
In [3]: from operator import setitem
In [4]: mylist = [0, 0, 0, 0, 0]
In [5]: indeces_to_replace = [0, 1, 3]
In [6]: deque(map(lambda x: setitem(mylist, x, 100), indeces_to_replace), maxlen=0)
Out[6]: deque([], maxlen=0)
In [7]: mylist
Out[7]: [100, 100, 0, 100, 0]
回答by Jesse Briggs
I like a list comprehension:
我喜欢列表理解:
[100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ]

