そもそも大きな問題を示しているのvariable1
は、一般的に悪い兆候です。複数の値が必要な場合は、名前が付けられた多くの変数ではなく、データ構造を使用してください。これにより、コードを何度も繰り返すことがなくなり、バグを防ぐことができます。
代わりにリストのリストを使用しましょう:
values = [
[(111, 222), (111, 333), (111, 444)],
[(555, 333), (555, 444), (555, 777)],
[(123, 444), (123, 888), (123, 999)]
]
ここで、サブリスト内の各タプルの2番目の要素のみを取得します。これは、リスト内包表記を使用して計算するのに十分簡単です。
>>> [[item[1] for item in sublist] for sublist in values]
[[222, 333, 444], [333, 444, 777], [444, 888, 999]]
次に、アイテム間の交差が必要です。これを使用itertools.combinations()
して、2つのさまざまなペアを取得します。
>>> for values, more_values in itertools.combinations(new_values, 2):
... set(values).intersection(more_values)
...
{444, 333}
{444}
{444}
したがって、これをまとめると、次のようになります。
import itertools
values = [
[(111, 222), (111, 333), (111, 444)],
[(555, 333), (555, 444), (555, 777)],
[(123, 444), (123, 888), (123, 999)]
]
sets_of_first_items = ({item[1] for item in sublist} for sublist in values)
for values, more_values in itertools.combinations(sets_of_first_items, 2):
print(values.intersection(more_values))
それは私たちに与えます:
{444, 333}
{444}
{444}
ここで行った変更は、内部リストをセット内包表記にすること、リストをセットに変換するためだけにリストを作成することを回避すること、および遅延評価されるため、リスト内包表記ではなくジェネレータ式を使用することでした。
最後に、交差点の生成に使用しているリストのインデックスが必要な場合は、enumerate()
組み込みの機能を使用するのは簡単です。
sets_of_first_items = ({item[1] for item in sublist} for sublist in values)
for (first_number, first_values), (second_number, second_values) in itertools.combinations(enumerate(sets_of_first_items), 2):
print("Intersection of {0} and {1}: {2}".format(first_number, second_number, first_values.intersection(second_values)))
それは私たちに与えます:
Intersection of 0 and 1: {444, 333}
Intersection of 0 and 2: {444}
Intersection of 1 and 2: {444}
編集:
tonyl7126で指摘されているように、これは、より優れたデータ構造を使用することで大いに役立つ可能性のある問題でもあります。ここでの最良のオプションは、一連の製品IDにユーザーIDのdictを使用することです。セットのみが必要で、後でセットに変換する場合は、データをリストとして保存する理由はありません。保存しようとしているデータの種類に対して、dictははるかに優れたソリューションです。
次の例を参照してください。
import itertools
values = {
"111": {222, 333, 444},
"555": {333, 444, 777},
"123": {444, 888, 999}
}
for (first_user, first_values), (second_user, second_values) in itertools.combinations(values.items(), 2):
print("Intersection of {0} and {1}: {2}".format(first_user, second_user, first_values.intersection(second_values)))
私たちに与える:
Intersection of 555 and 123: {444}
Intersection of 555 and 111: {444, 333}
Intersection of 123 and 111: {444}