<p>首先,您将看到一个很大的问题<code>variable1</code>通常是一个错误的符号-如果您想要有多个值,请使用一个数据结构,而不是使用很多带有编号名称的变量。这可以阻止你一遍又一遍地重复你的代码,并有助于阻止错误。在</p>
<p>让我们使用列表来代替:</p>
<pre><code>values = [
[(111, 222), (111, 333), (111, 444)],
[(555, 333), (555, 444), (555, 777)],
[(123, 444), (123, 888), (123, 999)]
]
</code></pre>
<p>现在我们只想得到子列表中每个元组的第二个元素。这很容易用<a href="https://www.youtube.com/watch?v=t85uBptTDYY" rel="nofollow noreferrer">list comprehension</a>计算:</p>
^{pr2}$
<p>然后,我们需要这些项之间的交集,我们使用<a href="http://docs.python.org/library/itertools.html#itertools.combinations" rel="nofollow noreferrer">^{<cd2>}</a>得到两个可能的不同对:</p>
<pre><code>>>> for values, more_values in itertools.combinations(new_values, 2):
... set(values).intersection(more_values)
...
{444, 333}
{444}
{444}
</code></pre>
<p>所以,如果我们把这个放在一起:</p>
<pre><code>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))
</code></pre>
<p>这给了我们:</p>
<pre><code>{444, 333}
{444}
{444}
</code></pre>
<p>我在这里所做的更改是使内部列表成为集合理解,避免创建一个列表只是为了将其转换为集合,并且使用生成器表达式而不是列表理解,因为它的计算是惰性的。在</p>
<p>最后一点,如果您想要我们用来生成交集的列表的索引,那么使用<a href="http://docs.python.org/library/functions.html#enumerate" rel="nofollow noreferrer">the ^{<cd3>} builtin</a>很简单:</p>
<pre><code>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)))
</code></pre>
<p>这给了我们:</p>
<pre><code>Intersection of 0 and 1: {444, 333}
Intersection of 0 and 2: {444}
Intersection of 1 and 2: {444}
</code></pre>
<p>编辑:</p>
<p>与<a href="https://stackoverflow.com/a/10576685/722121">noted by tonyl7126</a>一样,这也是一个可以通过使用更好的数据结构得到极大帮助的问题。这里最好的选择是使用一组产品id的dict。当你只需要一个集合,并打算稍后将其转换为集合时,没有理由将数据存储为一个列表,而dict对于你试图存储的数据类型是一个更好的解决方案。在</p>
<p>请参见以下示例:</p>
<pre><code>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)))
</code></pre>
<p>给我们:</p>
<pre><code>Intersection of 555 and 123: {444}
Intersection of 555 and 111: {444, 333}
Intersection of 123 and 111: {444}
</code></pre>