【发布时间】:2017-09-23 04:56:35
【问题描述】:
在我很快成功地用 C++ (see here) 编写了一个简约的 Python3.6 扩展模块之后,我计划提供一个与以下 Python 函数 iterUniqueCombos() 相同的 Python 模块:
def iterUniqueCombos(lstOfSortableItems, sizeOfCombo):
lstOfSortedItems = sorted(lstOfSortableItems)
sizeOfList = len(lstOfSortedItems)
lstComboCandidate = []
def idxNextUnique(idxItemOfList):
idxNextUniqueCandidate = idxItemOfList + 1
while (
idxNextUniqueCandidate < sizeOfList
and
lstOfSortedItems[idxNextUniqueCandidate] == lstOfSortedItems[idxItemOfList]
): # while
idxNextUniqueCandidate += 1
idxNextUnique = idxNextUniqueCandidate
return idxNextUnique
def combinate(idxItemOfList):
if len(lstComboCandidate) == sizeOfCombo:
yield tuple(lstComboCandidate)
elif sizeOfList - idxItemOfList >= sizeOfCombo - len(lstComboCandidate):
lstComboCandidate.append(lstOfSortedItems[idxItemOfList])
yield from combinate(idxItemOfList + 1)
lstComboCandidate.pop()
yield from combinate(idxNextUnique(idxItemOfList))
yield from combinate(0)
我对 Python 和 C++ 编程有一些基本了解,但完全不知道如何将 Python yield“翻译”成 Python 扩展模块的 C++ 代码。所以我的问题是:
如何编写能够返回 Python 迭代器对象的(Python 模块的)C++ 代码?
欢迎任何让我入门的提示。
更新(状态 2017-05-07):
评论:yield 没有 C++ 等价物。我将从在 Python 中手动实现迭代器协议开始,以摆脱思维定势的产量和产量。 – user2357112 Apr 26 at 1:16 和danny 答案中的提示 这个问题的答案与询问“如何在不使用 yield 的情况下实现迭代器”相同,但在 C++ 中扩展而不是纯 Python。 通过重写算法代码以消除 yield 并从头开始编写 Python 扩展模块的 C 代码(什么导致下雨Segmentation Fault 错误)。
我目前在这个问题上的最新知识是,使用Cython 可以将上面的 Python 代码(使用
yield)直接翻译成 C Python 扩展模块的代码。
这不仅可以按原样使用 Python 代码(无需重写任何内容),而且除此之外,Cython 使用 yield 的算法创建的扩展模块的速度至少运行两次与使用 __iter__ 和 __next__ 重写算法从迭代器类创建的扩展模块一样快(如果没有将 Cython 特定的速度优化代码添加到 Python 脚本中,则后者有效)。
【问题讨论】:
-
yield没有 C++ 等效项。我会从 Python 中的 implementing the iterator protocol manually 开始,以摆脱yield和yield from的心态。
标签: python c python-3.x iterator python-c-extension