如何找到列表和嵌套列表的交集?

时间:2014-10-31 21:27:14

标签: python list set intersection nested-lists

我有一份水果清单:

fruits = ["apple","banana"]

我还有一个嵌套的篮子列表,其中每个列表都包含一个字符串(篮子的名称)和一个水果列表。

baskets = [["basket1",["apple","banana","pear","strawberry"]],["basket2",["strawberry","pear","peach"]],["basket3",["peach","apple","banana"]]]

我想知道哪些篮子包含列表中的每个水果:我期望的结果是一个包含两个元素的列表," basket1"和" basket3"。

我认为交叉路口是实现这一目标最干净的方式,我尝试了以下方法:

myset = set(fruits).intersection(*map(set, set(baskets)))

但是我收到了TypeError"不可用的类型:' list'"。我知道我无法映射列表,但我认为使用函数" set"在两个列表上都会将它们转换为集合...有没有其他方法可以找到列表和列表列表的交集?

3 个答案:

答案 0 :(得分:4)

您可以循环查看篮子并检查当前篮子中fruits集合是否为subset水果,如果是,则存储当前篮子的名称。

>>> fruits = {"apple", "banana"} #notice the {}, or `set(["apple","banana"])` in Python 2.6 or earlier
>>> [b for b, f in baskets if fruits.issubset(f)]
['basket1', 'basket3']

答案 1 :(得分:0)

除了散列列表之外,您不能散列集合。它们都有相同的问题:因为它们是可变的,值可以改变它的内容,使任何包含它作为成员的集合或任何包含它作为键的字典突然失效。

可以哈希两个tuplefrozenset的不可变等价物。


与此同时,您解决此问题的尝试具有讽刺意味。把这条线分成几部分:

myset = set(fruits).intersection(*map(set, set(baskets)))

第一部分是:

baskets_set = set(baskets)

你有一份清单清单。您,set(baskets)正在尝试制作一组​​列表。你做不到的,因为列表不可用。


如果您刚删除它,并使用map(set, baskets),那么您将拥有一个集合的迭代器,这是完全有效的。

当然,只要你尝试迭代它,它就会尝试从baskets的第一个元素中创建一个列表,这样你就会再次遇到错误。


另外,即使您解决了这个问题,逻辑仍然没有任何意义。什么是一组,比方说3个字符串与一组,比如3个(冻结的)字符串集的交集?它是空的。这两套没有任何共同点。第二个元素的某些元素可能包含第一个元素的事实并不意味着第二个元素本身包含第一个元素。

答案 2 :(得分:0)

你可以用你的方法这样做:

fruits = ["apple","banana"]
baskets = [["basket1",["apple","banana","pear","strawberry"]],
           ["basket2",["strawberry","pear","peach"]],
           ["basket3",["peach","apple","banana"]]]

fruitset = set(fruits)
res =  set(b for b, s in ((b, set(c)) for b, c in baskets) if s & fruitset)
print res  # --> set(['basket1', 'basket3'])
相关问题