是否有一个相当于“map”的就地函数?在Python中?

发布于 2024-10-01 06:26:29 字数 188 浏览 6 评论 0原文

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

new_list = map(Sanitize, old_list)

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

I have a list of strings that I need to sanitize. I have a method for sanitizing them, so I could just do:

new_list = map(Sanitize, old_list)

but I don't need to keep the old list around. This got me wondering if there's an in-place equivalent to map. Easy enough to write a for loop for it (or a custom in-place map method), but is there anything built in?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风透绣罗衣 2024-10-08 06:26:33

最终,

old_list = map(Sanitize, old_list)

您将完全完成您所需要的工作。

您可能会反对创建新列表对象并对旧列表对象进行垃圾收集比使用现有列表对象慢。在实践中,这几乎永远不会成为问题(一次性分配一块内存不太可能成为瓶颈;也许如果您在循环中执行此操作或有一个非常长的列表,您可以尝试基准测试,但我仍然会与你打赌)。请记住,无论哪种方式,您都必须从头开始创建新字符串作为 Sanitize 的一部分,而且成本会高得多。

值得注意的是,正如 mluebke 所指出的那样,现在列表推导式被认为比 map 更加“Pythonic”(我相信 map 在该语言的未来版本)。

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

At the end of the day,

old_list = map(Sanitize, old_list)

will get done exactly what you need.

You might object that creating a new list object and garbage collecting the old one is slower than using an existing one. In practice, this should almost never be an issue (allocating as a one-off a chunk of memory is unlikely to be a bottleneck; maybe if you are doing this in a loop or have a massively long list you could try benchmarking, but I still would wager against you). Remember that either way you have to create new strings from scratch as part of Sanitize and that's going to be much more expensive.

Worth noting, as mluebke notes, is that these days list comprehensions are considered much more "pythonic" than map (I believe map is deprecated in future versions of the language).

Edit: Ah, I see you are trying to edit the values of arguments passed to a function. I'd fairly strongly argue that this is "unpythonic" and that you should return the new list as one of your return values (remember, using tuples you can have more than one return value).

红ご颜醉 2024-10-08 06:26:32

你必须循环:

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

没有任何内置的东西。

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

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

map_in_place(Sanitize, old_list)

You have to loop:

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

There's nothing built-in.

As suggested in the comments: a function as desired by the OP:

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

map_in_place(Sanitize, old_list)
欢烬 2024-10-08 06:26:32

我认为你能得到的最接近的是:

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

它“就地”修改对象 x 而不仅仅是重新分配它,但它仍然创建一个单独的临时 map 对象(或 Python 2 中的列表)。所以你仍然会使用一些额外的内存。我对其工作原理的解释如下。


与使用 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)

I think the closest you can get is this:

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

It does it "in-place" in the sense that it modifies the object x instead of just reassigning it, but it does still create a separate temporary map object (or list in Python 2). So you will still have a little extra memory being used. My explanation for how this works is below.


Similar to using this[0] = something, you can also specify slices:

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

Since slices can have parts left out (the start, stop, or step), you can change the whole list by something like this:

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

This (as seen above) is capable of changing even the length of the list. As can be seen below, this is indeed changing the actual object, not redefining the variable:

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

It doesn't necessarily need to be a list at the right end of the assignment. Anything that is iterable can be on that side. In fact, you could even have a generator:

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

or the returns of map() (a list in Python 2; a map object in Python 3):

>>> x = ["1", "2", "3", "4"]
>>> x[:] = map(int, x)
半边脸i 2024-10-08 06:26:30

答案很简单:不。

当答案为时,“XXX是否存在”形式的问题永远不会得到直接回答,所以我想我应该把它放在那里。

大多数 itertools 帮助程序和内置函数都在通用迭代器上运行。 mapfilter、列表推导式、for——它们都适用于迭代器,而不修改原始容器(如果有)。

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

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

The answer is simply: no.

Questions of the form "does XXX exist" never tend to get answered directly when the answer is no, so I figured I'd put it out there.

Most itertools helpers and builtins operate on generic iterators. map, filter, list comprehensions, for--they all work on iterators, not modifying the original container (if any).

Why aren't there any mutating functions in this category? Because there's no generic, universal way to assign values to containers with respect to their keys and values. For example, basic dict iterators (for x in {}) iterate over the keys, and assigning to a dict uses the result of the dict as the parameter to []. Lists, on the other hand, iterate over the values, and assignment uses the implicit index. The underlying consistency isn't there to provide generic functions like this, so there's nothing like this in itertools or in the builtins.

They could provide it as a methods of list and dict, but presently they don't. You'll just need to roll your own.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文