Her*_*rms 13 python dictionary in-place
我有一个需要消毒的字符串列表.我有一种消毒方法,所以我可以这样做:
new_list = map(Sanitize, old_list)
Run Code Online (Sandbox Code Playgroud)
但我不需要保留旧列表.这让我想知道是否有一个相当于地图的就地.很容易为它编写for循环(或自定义就地映射方法),但是内置了什么?
Gle*_*ard 12
答案很简单:不.
当答案为否时,"XXX存在"形式的问题从未倾向于直接回答,所以我想我会把它放在那里.
大多数itertools助手和内置函数都在泛型迭代器上运行. map,filter列表for推导, - 它们都在迭代器上工作,而不是修改原始容器(如果有的话).
为什么这个类别中没有任何变异功能?因为没有通用的通用方法来为容器的键和值赋值.例如,基本的dict迭代器(for x in {})遍历键,并且分配给dict使用dict的结果作为[]的参数.另一方面,列表迭代值,赋值使用隐式索引.底层的一致性不是提供像这样的通用函数,因此itertools在内置函数中或内部都没有这样的东西.
他们可以提供它的方法list和dict,但目前他们没有.你只需要自己动手.
你必须循环:
for i in range(len(old_list)):
old_list[i] = Sanitize(old_list[i])
Run Code Online (Sandbox Code Playgroud)
内置任何东西都没有.
正如评论中所建议的那样:OP所需的功能:
def map_in_place(fn, l):
for i in range(len(l)):
l[i] = fn(l[i])
map_in_place(Sanitize, old_list)
Run Code Online (Sandbox Code Playgroud)
我认为你能得到的最接近的是:
>>> x = ["1", "2", "3", "4"]
>>> x[:] = map(int, x)
Run Code Online (Sandbox Code Playgroud)
它“就地”执行此操作,即修改对象x而不只是重新分配对象,但它仍然创建一个单独的临时map对象(或 Python 2 中的列表)。所以你仍然会使用一些额外的内存。我对其工作原理的解释如下。
与使用类似this[0] = something,您也可以指定切片:
>>> x = [1, 2, 3, 4]
>>> x[1:3] = [0, 0]
>>> x
[1, 0, 0, 4]
Run Code Online (Sandbox Code Playgroud)
由于切片可以省略某些部分(开始、停止或步骤),因此您可以通过如下方式更改整个列表:
>>> x = [1, 2, 3, 4]
>>> x[:] = [4, 5, 6]
>>> x
[4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
这(如上所示)甚至能够改变列表的长度。如下所示,这确实是在改变实际对象,而不是重新定义变量:
>>> x = [1, 2, 3, 4]
>>> y = x
>>> x[:] = [3, 4]
>>> y
[3, 4]
Run Code Online (Sandbox Code Playgroud)
它不一定需要是作业右端的列表。任何可迭代的东西都可以在那一侧。事实上,你甚至可以拥有一个生成器:
>>> x = ["1", "2", "3", "4"]
>>> x[:] = (int(y) for y in x)
>>> x
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
map()或(Python 2 中的列表;mapPython 3 中的对象)的返回:
>>> x = ["1", "2", "3", "4"]
>>> x[:] = map(int, x)
Run Code Online (Sandbox Code Playgroud)