微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Itertools 链在 Cython 中的行为不同

如何解决Itertools 链在 Cython 中的行为不同

我有两组物品,A 和 B,其中 A 预计更大。我想要来自 A U B 的所有给定大小的无序元组,其中至少包含一个来自 B 的元素。

我的方法是取 B 的每个元素,取它的 product 和 A 的所有 (k-1)-元组 combinations,然后将该元素添加到 A 中,以便将其包含在内与 B 的其余成员组合。然后我chain 将这些产品放在一起。

我在 Python 中使用它,但是当我将它放入 Cython 时,行为发生了变化。 (在这个例子中,我只是在做对,但我想概括为一个 5 元组。我的示例集有 4 个和 2 个项目,但我希望有数百个——这就是为什么我使用生成器而不是仅仅扩展前面的元组。)

Python 版本(所需行为):

from itertools import combinations,chain,product

def get_colder_python():
    inventory = {"hat","shoes","shirt","socks"}
    add_items = {"pants","jacket"}
    combo_chain = []
    for a in add_items:
        next_iterator = product([a],combinations(inventory,1))
        combo_chain.append((x,*y) for x,y in next_iterator)
        inventory.add(a)    
    combos = chain.from_iterable(combo_chain)
    return list(combos)

print(get_colder_python())

结果:

[('jacket','shoes'),('jacket','shirt'),'hat'),'socks'),('pants','jacket'),'socks')]

Cython 版本:

%%cython

from itertools import chain,product,combinations

cdef get_colder_cython():
    inventory = {"hat",y in next_iterator)
        inventory.add(a)
    combos = chain.from_iterable(combo_chain)
    return list(combos)

print(get_colder_cython())

结果

[('pants','socks')]

它只是从链中获取第二个迭代器。

我现在的解决方法是“不要为此使用 Cython”,我知道 itertools 已经过优化,因此 Cython 不应该带来很大的速度提升,但我想了解为什么它的行为有所不同.

解决方法

只是提供更多细节:生成器变量范围是 a long-standing bug on Cython

行为不同的行是

((x,*y) for x,y in next_iterator)

在这两种情况下,它都是惰性执行的。在 Python 中,它查找 next_iterator,存储对它的引用,并使用该引用初始化生成器表达式。

在 Cython 中,当生成器表达式被创建时它几乎什么都不做 - 而 next_iterator 只在表达式被执行时被查找。此时它已经被多次重新分配。

我的建议是使用列表理解,因为它们会在创建时立即执行。但这显然失去了懒惰的好处。嵌套生成器函数也可能工作:

def gen(next_iterator):
    yield from ((x,y in next_iterator)
combo_chain.append(gen)

虽然创建一个函数并不便宜,所以你可能会发现这对性能不利。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?