2016-11-18 47 views
0

我将Python 2中的一些代码转换为Python 3.我遇到了一些Python 2内置函数用于生成列表的问题,但现在生成迭代器在Python 3中。我想重写这段代码,但没有找到一种方法使程序工作,而没有将迭代器转换为列表,这看起来效率不高。问题是,是否有办法使用迭代器而不是将迭代器转换为列表来使这些代码工作?从`zip`迭代器构建的python 3`product`迭代器中解包值

下面是Python 3程序的简化版本。

from itertools import product 

points = {(1, 1), (0.5, 0.5), (0.75, 0.75)} 
labels = range(len(points)) 

zips = zip(points, labels) 
for pair in product(zips,zips): 
    if pair[0][1] != pair[1][1]: 
     print("good") 

请注意,我将for循环简化为只打印“好”。真正的程序计算欧几里德距离,但“好”保留了基本思想。

此外请注意,在Python 3中,ziprange内置了生成器和迭代器。然后itertools函数product根据ziprange迭代器创建迭代器。

当我在Python 3中运行这段代码时,循环刚刚结束而没有打印出“好”,这是不准确的。该代码似乎只是绕过循环,因为我不认为它在pair中找到任何值。

我找到的解决方案只是将变量zips转换为列表。所以代码看起来像。

from itertools import product 

points = {(1, 1), (0.5, 0.5), (0.75, 0.75)} 
labels = range(len(points)) 

zips = list(zip(points, labels)) 
for pair in product(zips,zips): 
    if pair[0][1] != pair[1][1]: 
     print("good") 

在修改后的代码的东西的工作,但我失去了漂亮的迭代器结构。

再次,问题是我是否可以重写这段代码而不必将迭代器转换为列表?

回答

1

不是传递zipsproduct两次,使用repeat参数:

for pair in product(zip(points, labels), repeat=2): 
    ... 

注意product将兑现在引擎盖下的迭代器呢。它必须,因为它需要不止一次地遍历元素。

+0

哦,这太好了。这工作得很好。嗯,你知道当我使用'产品(拉链,拉链)'时代码不起作用吗?似乎我缺少为什么这个更新的代码工作。 – krishnab

+0

@krishnab:对于'product(zips,zips)','product'认为参数是独立的,当前进一个迭代器推进另一个迭代器时会混淆。使用'repeat',它知道只实现迭代器一次。 – user2357112

+0

啊好的。现在我懂了。非常感谢你的帮助。 – krishnab