2017-03-04 112 views
2

相交嵌套列表,我想相交兩個嵌套表:使用lambda函數

source = [['one', 'two', 'three'], ['four', 'five', 'six'], ['seven', 'eight', 'nine']] 
target = [['three', 'whatever'], ['four', 'whatever'], ['whatever', 'whatever']] 

這樣我就可以在source返回列表,其中發現十字路口:

result = [['one', 'two', 'three'], ['four', 'five', 'six']] 

我該怎麼辦這使用lambda

+0

,你到底是什麼意思?你的意思是子列表中的一個項目應該在另一個子列表的一個項目中?或者它應該在「相同的」子列表(相同的索引)? – MSeifert

+0

@MSeifert是的,子列表中的一項應該與另一個子列表中的項目相同。 –

回答

5

您可以使用設置來檢查是否有元素之間任何交集:

[s for s in source if any(set(s) & set(t) for t in target)] 
# [['one', 'two', 'three'], ['four', 'five', 'six']] 

如果目標轉換爲集前手名單這可能會略微高效:

target_set = [set(t) for t in target] 
[s for s in source if any(set(s) & t for t in target_set)] 

當說lambda,也許你需要一個filter功能:

filter(lambda s: any(set(s) & t for t in target_set), source) 

或者在Python 3:

list(filter(lambda s: any(set(s) & t for t in target_set), source)) 

好像你的邏輯就相當於爲@JohnColeman評論如下:

target_set = {j for i in target for j in i}  
filter(lambda s: set(s) & target_set, source) 

# [['one', 'two', 'three'], ['four', 'five', 'six']] 
+1

「如果事先將目標轉換爲設置列表,這可能會稍微更有效率」 - 爲什麼不通過組合將其轉換爲單個集合呢? –

+0

@JohnColeman啊,我認爲你是對的,邏輯似乎是這樣的。 – Psidom

+0

'target_set = reduce(lambda s,b:s | b,[set(t)for t in target],set())'然後'[s for s in source if set(s)&target_set] – galfisher

2

你可以簡單地在lambda中使用set.difference結合過濾器:

list(filter(lambda s: set(s).difference(*target) != set(s), 
      source)) 

這將保留包含至少一個項目在任何target列表中的任何列表。

或者,如果你不喜歡set是你可以做的檢查明確:

list(filter(lambda s: any(item in sublist for sublist in target for item in s), 
      source)) 
當你說相交