Python 中的 filter、map 和 reduce 函数是否会创建列表的新副本?

5

使用Python 2.7。假设我们有一个list_of_nums = [1,2,2,3,4,5],我们想要删除所有的2。我们可以通过list_of_nums[:] = filter(lambda x: x! = 2, list_of_nums)或者list_of_nums = filter(lambda x: x! = 2, list_of_nums)来实现。这是一种“原地”替换吗?同时,当我们使用filter时,我们是否创建了列表的副本?


尝试使用 is 来判断它们是否是同一个 对象。如果你尝试将返回值赋值给变量,会得到 None 吗?或者在调用方法之前和之后使用id(),结果是否相同? - wwii
2
@wwii 使用 id 可能会更加说服他。 - Rockybilly
1
另外,当我们使用过滤器时,我们是否会创建列表的副本?不会,它只是在列表(或其他可迭代对象)参数上进行迭代。顺便说一下,在Python 3中,“filter”和“map”返回迭代器,而不是列表。 - PM 2Ring
1
请注意,使用list_of_nums[:]的原地版本比将新列表重新绑定到list_of_nums名称要慢。 - PM 2Ring
1个回答

5
list_of_nums[:] = filter(lambda x: x != 2, list_of_nums)

并且

list_of_nums = filter(lambda x: x != 2, list_of_nums)

“复制”和“克隆”是两种不同的操作,最终得到的结果基本相同。

在这两种情况下,

filter(lambda x: x != 2, list_of_nums)

该函数在 Python 2 中返回一个包含符合过滤条件的元素的新列表,而在 Python 3 中返回能够迭代访问与 list_of_nums 中相同元素的可迭代对象。

第一种情况中,

list_of_nums[:] = filter(lambda x: x != 2, list_of_nums)

然后从list_of_nums中删除所有项目,并用新列表或可迭代对象中的项目替换它们。

第二种情况,

list_of_nums = filter(lambda x: x != 2, list_of_nums)

将新列表分配给变量list_of_nums

这个操作产生影响的时候是这样的:

def processItemsNotTwo_case1(list_of_nums):
    list_of_nums[:] = filter(lambda x: x != 2, list_of_nums)
    # do stuff here
    # return something

def processItemsNotTwo_case2(list_of_nums):
    list_of_nums = filter(lambda x: x != 2, list_of_nums)
    # do stuff here
    # return something

list1 = [1,2,2,3,4,5]
processItemsNotTwo_case1(list1)
list2 = [1,2,2,3,4,5]
processItemsNotTwo_case2(list2)

使用以下代码,list1 的新内容为 [1,3,4,5],而 list2 的原始内容保持不变:[1,2,2,3,4,5]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接