0

我想知道执行此代码时会发生什么,以及是否有更好的方法来完成相同的任务。是否在内存中生成列表以执行排序,然后将 bar 分配为 foo.values() 的迭代器?或者可能 foo.values() 在分配的字典内存空间中排序(似乎不太可能)?

想象一下列表中的第一个值,整数,指的是文件中的行号。我想打开文件并仅用列表中的其余数据更新 foo.values() 列表中引用的行(EG 更新第 1 行,字符串为“123”和“097”)。

from itertools import imap

>>> foo = {'2134':[1, '123', '097'], '6543543':[3, '1'], '12315':[2, '454']}
>>> bar = imap([].sort(), foo.values())

谢谢~

4

1 回答 1

5

首先,您正在传递[].sort(),这只是None,作为 的第一个参数imap,这意味着它什么都不做。正如文档解释的那样:“如果函数设置为无,则 imap() 将参数作为元组返回。”

要将可调用对象传递给类似 的高阶函数imap,您必须传递可调用对象本身,而不是调用它并传递结果。

另外,你不想[].sort在这里;这是一个没有参数的可调用对象,它只对一个空列表进行排序,这是无用的。

您可能想要list.sortunbound 方法,它是一个可调用的,带有一个参数,它将对给定的任何列表进行排序。


所以,如果你这样做了,你会创建一个迭代器,如果你迭代它,它会生成一堆None值,并且作为副作用,将每个列表排序到foo.values(). 不会在任何地方创建新列表,因为会list.sort就地改变列表并返回None

但是由于您无论如何都不会对其进行迭代,因此您放入什么并不重要imap;它实际上所做的实际上什么都不是。


一般来说,滥用map/ imap/理解/等。因为表达式的副作用是一个坏主意。生成无用值但无论如何您都必须进行迭代的迭代器充其量只会造成混乱。

这里要做的简单的事情是只使用一个循环:

for value in foo.values():
    value.sort()

或者,不是就地排序,而是生成新的排序值:

bar = imap(sorted, foo.values())

现在,当您进行迭代bar时,每个列表都将被排序并提供给您,因此您可以使用它。如果你迭代它,它将内存中为每个列表生成一个排序列表……但一次只有一个是活着的(除非你明确地将它们存储在某个地方)。

于 2013-10-17T22:29:47.200 回答