理解:参考组件

时间:2011-02-20 09:55:08

标签: python interpreter list-comprehension internals

总之:我需要编写一个列表理解,其中我引用列表理解创建的列表。

这可能不是你每天都需要做的事情,但我认为这也不常见。

也许这里没有答案 - 但是,请不要告诉我,我应该使用 for 循环。这可能是正确的,但没有用。原因是问题域:这行代码是ETL模块的一部分,因此性能是相关的,因此需要避免创建临时容器 - 因此我希望在L / C中编写此步骤。如果for循环在这里对我有用,我只想编码一个。

无论如何,我无法写出这个特定的列表理解。原因是:我需要写的表达式有这样的形式:

[ some_function(s) for s in raw_data if s not in this_list ]

在该伪代码中,“this_list”指的是通过评估该列表理解而创建的列表。这就是为什么我被卡住 - 因为this_list在我的列表理解被评估之前没有构建,并且因为这个列表还没有在我需要引用它的时候构建,所以我不知道如何引用它

我到目前为止所考虑的内容(可能基于一个或多个错误的假设,但我不确切知道在哪里):

  • 不是python解释器 给这个列表正在建设中 一个名字?我想是的

  • 可能会采用临时名称 从一些用于构建的绑定方法 我的清单('sum'?)

  • 但即使我去麻烦了 找到绑定方法并假设 它确实是临时名称 由python解释器使用 当它在下面时参考列表 施工,我很确定你 不能引用绑定方法 直;我不知道这样的 明确的规则,但那些方法(在 至少我实际上是少数几个 看着)是无效的python 句法。我猜是有一个原因 这样我们就不会把它们写进去了 我们的代码。

这就是我所谓推理的链条,这让我得出结论,或者至少猜测,我把自己编成了一个角落。我仍然认为我应该先与社区核实这一点,然后再转向另一个方向。

4 个答案:

答案 0 :(得分:3)

过去有一种方法可以使用未记录的事实来做到这一点,即在构建列表时,其值存储在名为_[1].__self__的局部变量中。然而,退出Python 2.7(可能更早,我没有密切关注)。

如果先设置外部数据结构,则可以在单个列表推导中执行所需操作。由于您的所有伪代码似乎都在使用this_list,因此检查它是否已经包含每个s - 即成员资格测试 - 我已将其更改为{{1}将set命名为优化(如果列表很大,检查seen中的成员资格可能会非常慢)。这就是我的意思:

list

如果您无法访问raw_data = [c for c in 'abcdaebfc'] seen = set() def some_function(s): seen.add(s) return s print [ some_function(s) for s in raw_data if s not in seen ] # ['a', 'b', 'c', 'd', 'e', 'f'] ,可以在自己的包装函数中调用它,在返回之前将其返回值添加到some_function集。

尽管它不是列表理解,但我将整个事物封装在函数中以使重用更容易:

seen

在任何一种情况下,我都觉得奇怪的是,你想要引用的伪代码中构建的列表不是由def some_function(s): # do something with or to 's'... return s def add_unique(function, data): result = [] seen = set(result) # init to empty set for s in data: if s not in seen: t = function(s) result.append(t) seen.add(t) return result print add_unique(some_function, raw_data) # ['a', 'b', 'c', 'd', 'e', 'f'] 值的子集组成,而是调用{{1}的结果在每一个上 - 即转换后的数据 - 这自然让人不知道raw_data做了什么,使得它的返回值可能与现有的some_function项的值相匹配。

答案 1 :(得分:2)

据我所知,在构建列表时,没有办法访问列表理解。

正如KennyTM所提到的(如果条目的顺序不相关),那么您可以使用set代替。如果您使用的是Python 2.7 / 3.1及更高版本,您甚至可以获得设置理解:

{ some_function(s) for s in raw_data }

否则,for循环也不是那么糟糕(尽管它会扩展得非常糟糕)

l = []
for s in raw_data:
    item = somefunction(s)
    if item not in l:
        l.append(item)

答案 2 :(得分:2)

我不明白为什么你需要一次性完成这项工作。首先迭代初始数据以消除重复 - 或者更好的是,将其转换为KennyTM建议的set - 然后执行列表理解。

请注意,即使您可以引用“正在构建的列表”,您的方法仍会失败,因为s无论如何都不在列表中 - some_function(s)的结果是。

答案 3 :(得分:0)

你为什么不这样做:[ some_function(s) for s in set(raw_data) ]

那应该做你要求的。除非您需要保留上一个列表的顺序。