2014-10-31 42 views
0

我有水果的清單:如何找到列表和嵌套列表的交集?

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))) 

但我得到一個類型錯誤「unhashable類型:‘名單’」。我知道我不能映射列表,但我認爲在這兩個列表上使用函數「set」會將它們轉換爲集...有沒有其他方法可以找到列表和列表的列表的交集?

+2

? – Sasa 2014-10-31 21:28:42

+0

@Sasa它會有所作爲嗎? – kormak 2014-10-31 21:32:25

+0

@kormak:在這種情況下不是_huge_,而是。而不必在'baskets'列表中查看每個列表的第二個元素,您只需在'baskets'字典中查看每個值即可。一般來說,爲作業使用正確的數據結構會讓您的生活更輕鬆。 – abarnert 2014-10-31 21:59:56

回答

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'] 
+0

我收到以下錯誤:AttributeError:'列表'對象沒有屬性'issubset' 該文件說issubset適用於集,我是否需要將列表轉換爲集?如果是這樣,怎麼樣?正如我在我的文章中所提到的,使用set(fruits)或set(籃子)引發了一個不可干擾的類型錯誤。 – kormak 2014-10-31 21:52:30

+1

@kormak:不,'set(fruits)'不會引發一個不可能被幹擾的類型錯誤,它是'set(籃子)'這樣做的 - 這是Ashwini沒有做的。 (這就是爲什麼把一堆表達式加入到一個大表達式中會使得調試變得更加困難,你不知道那些調用'set'的函數正在增加。) – abarnert 2014-10-31 21:54:33

+1

@kormak:另外,請注意,Ashwini將'fruits'定義爲首先設置,所以問題甚至沒有出現。 – abarnert 2014-10-31 21:54:53

0

你不能哈希集合超過你可以散列表。它們都有相同的問題:因爲它們是可變的,所以一個值可以改變它的內容,使得任何包含它作爲成員的集合或任何包含它的字典突然失效。

可以散列兩者的不可變等價物,tuplefrozenset


同時,您的直接問題是您試圖解決此問題的諷刺。打破這種線下成片:

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

第一部分是這樣的:

baskets_set = set(baskets) 

你有一個列表的列表。你,set(baskets)正在嘗試製作一組​​列表。你不能這樣做,因爲列表是不可散列的。


如果你只是刪除了,並用map(set, baskets),你將不得不套的迭代器,這是一個完全有效的事情。

當然,只要您嘗試迭代它,它會嘗試從baskets的第一個元素(這是一個列表)中創建一個元素,所以您將再次遇到錯誤。


另外,即使你解決了這個問題,邏輯依然沒有任何意義。一組3個字符串與一組3個(冷凍)字符串集合的交集是什麼?它是空的。這兩套沒有任何共同點。第二個元素包含第一個元素的事實並不意味着第二個元素包含第一個元素。

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'])