在python中是否存在等效于'map'的位置?

时间:2010-11-10 19:41:19

标签: python dictionary in-place

我有一个需要清理的字符串列表。我有一种消毒方法,所以我可以这样做:

new_list = map(Sanitize, old_list)

但我不需要保留旧列表。这让我想知道是否有一个相当于地图的就地。很容易为它编写for循环(或自定义就地映射方法),但是内置了什么?

4 个答案:

答案 0 :(得分:11)

答案很简单:不。

当答案是 no 时,“XXX存在”形式的问题从未倾向于直接得到答案,所以我想我会把它放在那里。

大多数itertools助手和内置函数都使用泛型迭代器。 mapfilter,列表推导,for - 它们都在迭代器上工作,而不是修改原始容器(如果有的话)。

为什么这个类别中没有任何变异功能?因为没有通用的通用方法来为容器的键和值赋值。例如,基本的dict迭代器(for x in {})遍历键,并且分配给dict使用dict的结果作为[]的参数。另一方面,列表迭代,赋值使用隐式索引。底层的一致性不是提供像这样的通用函数,所以在itertools或内置函数中没有这样的东西。

他们可以将其作为listdict的方法提供,但目前他们没有。你只需要自己动手。

答案 1 :(得分:5)

你必须循环:

for i in range(len(old_list)):
    old_list[i] = Sanitize(old_list[i])

没有任何内置功能。<​​/ p>

正如评论中所建议的那样:OP所需的功能:

def map_in_place(fn, l):
    for i in range(len(l)):
        l[i] = fn(l[i])

map_in_place(Sanitize, old_list)

答案 2 :(得分:2)

在一天结束时,

old_list = map(Sanitize, old_list)

将完全按照您的需要完成。

您可能会反对创建新的列表对象并收集旧的列表对象比使用现有列表对象慢。在实践中,这几乎不应该是一个问题(分配作为一次性的一块内存不太可能是一个瓶颈;也许如果你在一个循环中做这个或有一个很长的列表,你可以尝试基准测试,但我仍然会打赌你)。请记住,无论哪种方式,您都必须从头开始创建新字符串作为Sanitize的一部分,这将会更加昂贵。

值得注意的是,mluebke注意到,这些日子列表理解被认为比map更加“pythonic”(我相信map在该语言的未来版本中已被弃用)

编辑:啊,我看到你正在尝试编辑传递给函数的参数值。我非常强烈地认为这是“unpythonic”并且您应该将新列表作为返回值之一返回(请记住,使用元组可以有多个返回值)。

答案 3 :(得分:0)

与使用this[0] = something类似,您也可以指定切片:

>>> x = [1, 2, 3, 4]
>>> x[1:3] = [0, 0]
>>> x
[1, 0, 0, 4]

由于切片可以省略部分(开始,停止或步骤),您可以通过以下方式更改整个列表:

>>> x = [1, 2, 3, 4]
>>> x[:] = [4, 5, 6]
>>> x
[4, 5, 6]

这(如上所示)能够改变列表的长度。如下所示,这确实改变了实际对象,而不是重新定义变量:

>>> x = [1, 2, 3, 4]
>>> y = x
>>> x[:] = [3, 4]
>>> y
[3, 4]

它不一定需要是作业右端的列表。任何可迭代的东西都可以在那一边。事实上,你甚至可以拥有一台发电机:

>>> x = ["1", "2", "3", "4"]
>>> x[:] = (int(y) for y in x)
>>> x
[1, 2, 3, 4]

map()的返回(Python 2中的列表; Python 3中的map对象):

>>> x = ["1", "2", "3", "4"]
>>> x[:] = map(int, x)