7

我有一个清单:mylist = [0, 0, 0, 0, 0]

我只想用一个共同的数字替换选定的元素,比如第一个、第二个和第四个A = 100

一种方法:

mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]

我正在寻找一种单线或更简单的方法来做到这一点。更通用和灵活的答案是可取的。

4

6 回答 6

8

特别是因为你要替换相当大的一部分list,我会一成不变地这样做:

mylist = [100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)]

list在 Python 中,创建一个 new是单行的,而改变 alist需要一个显式循环,这是有意的。通常,如果你不知道你想要哪个,你想要新的list. (在某些情况下它更慢或更复杂,或者你有一些其他代码引用了相同的代码list并且需要看到它发生了变异,或者其他什么,这就是为什么这是“通常”而不是“总是”。)

如果您想多次执行此操作,我会将其包装在一个函数中,正如 Volatility 所建议的那样:

def elements_replaced(lst, new_element, indices):
    return [new_element if i in indices else e for i, e in enumerate(lst)]

我个人可能会把它做成一个生成器,所以它会产生一个迭代而不是返回一个列表,即使我永远不需要它,只是因为我那样愚蠢。但如果你真的需要它:

myiter = (100 if i in (0, 1, 3) else e for i, e in enumerate(mylist))

或者:

def elements_replaced(lst, new_element, indices):
    for i, e in enumerate(lst):
        if i in indices:
            yield new_element
        else:
            yield e
于 2013-01-16T02:31:14.427 回答
2
def replace_element(lst, new_element, indices):
    for i in indices:
        lst[i] = new_element
    return lst

这绝对是一个更通用的解决方案,但不是单行的。例如,在您的情况下,您会调用:

mylist = replace_element(mylist, 100, [0, 1, 3])
于 2013-01-16T02:24:29.367 回答
1

如果你不反对使用 Numpy 支持这一点np.ndarray

>>> a = np.zeros(5)
>>> a[[0,1,3]] = 100
>>> a
array([ 100.,  100.,    0.,  100.,    0.])
于 2013-01-16T02:26:52.727 回答
0

这是你要找的吗?列出要更改的索引,然后遍历该列表以更改值。

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]
于 2013-01-16T02:20:47.477 回答
0

不是这个的超级粉丝,但你可以试试这个(尽管我认为以上所有内容都更加简洁易读):

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]

除了值得怀疑的可读性和导入的需要之外,@abarnert 还指出了一些额外的问题,即它map仍然创建了一个不必要的列表(它被丢弃_但仍然创建了)并且它在 Python 3 中不起作用,因为map 返回一个Python 3.x 中的迭代器。您可以使用这六个模块map从 Python 2.x 模拟 Python 3.x 中的行为,并结合collections.deque(再次如 @abarnert 建议的那样),您可以实现相同的输出,而无需在内存中创建额外的列表,因为deque可以包含最多0项目的将丢弃它从map迭代器接收到的所有内容(请注意,使用six,map是通过使用 模拟的itertools.imap)。

同样,绝对没有必要使用它 - 上面/下面的每个解决方案都更好:)

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]
于 2013-01-16T02:31:49.073 回答
0

我喜欢列表理解:

[100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ]
于 2013-01-16T02:32:46.410 回答