2016-11-18 2 views
0

私はいくつかのコードをPython 2からPython 3に変換しています。リストを生成するためにいくつかのPython 2組み込み関数が使われていましたが、私はこのコードを書き直したかったのですが、イテレータをリストに変換せずにプログラムを動作させる方法を見つけられませんでした。これはあまり効率的ではないようです。質問は、イテレータをリストに変換するのではなく、イテレータを使用してこのコードを動作させる方法があるかどうかです。`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の組み込み関数が生成され、イテレータが生成されることに注意してください。次にproduct関数のitertoolsは、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") 

変更されたコードでは機能しますが、素晴らしいイテレータ構造が失われました。

もう一度質問しますが、イテレータをリストに変換しなくてもこのコードを書き直すことができますか? productはとにかくフードの下イテレータを具現化すること

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

注:

答えて

1

は、代わりに二回productzipsを渡すので、repeat引数を使用します。これは、要素に対して複数回反復する必要があるためです。

+0

これは素晴らしいです。これはうまくいった。うーん、私が 'product(zips、zips) 'を使用したときにコードがうまくいかなかったことを知っていますか?なぜ私はこの更新されたコードが動作していないようです。 – krishnab

+0

@krishnab: 'product(zips、zips)'では、 'product'は引数が独立していると考え、一方のイテレータを進めると他方のイテレータを進めるときに混乱します。 'repeat'では、イテレータを一度のみ実現することを知っています。 – user2357112

+0

ああ。今私はそれを得る。助けてくれてありがとう。 – krishnab

関連する問題