3

我一直在尝试移植一个向量数学库来进行加密 ,但遇到了模拟可迭代类型的问题。

我有一个带有内部可迭代的 Vector 类。这是核心的简化版本:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(self, other)))

在纯 python 中(Vector(1,2,3) + Vector(3,4,5))返回Vector(4,6,8)如您所料。但是在转码之后,相同的代码失败了——在 Javascript 中,它似乎在其可迭代对象上zip()期望一个 Javascript函数。map()

在这种情况下,我可以通过显式定位底层存储来解决它,因为它是使用 *args 创建的,所以它似乎具有所需的方法:

def __add__(self, other):
    pairwise = zip(self.values, other.values)
    return Vector( *(itertools.starmap(lambda a, b: a + b, pairwise)))

但是将它耦合到内部容器对我来说感觉很不稳定,我认为创建迭代器和星图会产生开销。

那么 - 解决这个问题的正确方法是什么?我可以map()在课堂上添加一个吗?如果是这样,正确的签名是什么?底层的 JS 似乎依赖于 JS 范围行为......这让我害怕......

4

1 回答 1

0

关键是zip它还没有适应迭代器。一个简单的解决方法是将 args 转换zip为列表。以下代码有效:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(list (self), list (other))))

    def __str__ (self):
        return self.values

#__pragma__ ('opov')

print (Vector(1,2,3) + Vector(3,4,5))

#__pragma__ ('noopov')

这将打印:

4,6,8

很抱歉回答迟了,在过去的几个月里一直传播得有点薄。我发现为迭代器调整 zip 非常复杂,这就是它尚未完成的原因。

想想看,将参数转换为列表可以自动完成。尽管运行时测试有(很小的)开销,但我将添加(问题#369),因为它更好地匹配预期行为。

它在 3.6.44 版中,您的代码现在应该可以正常工作而无需更改(使用 -e 6 开关来激活迭代器)。

于 2017-08-05T12:32:24.980 回答