使用lambda函数相交嵌套列表

时间:2021-07-13 10:10:52

I would like to intersect two nested lists:

我想交叉两个嵌套列表:

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

So I can return the lists in source where intersections were found:

所以我可以在源代码中返回找到交叉点的列表:

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

How can I do this using lambda?

我怎么能用lambda做到这一点?

2 个解决方案

#1


5  

You can use set to check if there is any intersection between elements:

您可以使用set来检查元素之间是否存在任何交集:

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

This could be slightly more efficient if convert the target to a list of sets before hand:

如果先将目标转换为集合列表,这可能会稍微提高效率:

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

When saying lambda, maybe you need a filter function:

说lambda时,也许你需要一个过滤功能:

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

Or in python 3:

或者在python 3中:

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

It seems like your logic is equivalent to the following as @JohnColeman commented:

看起来你的逻辑与@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']]

#2


2  

You can simply use set.difference in the lambda combined with a filter:

您可以简单地在lambda中使用set.difference并结合过滤器:

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

This will keep any list that contains at least one item that is in any of the target-lists.

这将保留包含任何目标列表中的至少一个项目的任何列表。

Or if you don't like sets you can do the checks explicitly:

或者,如果您不喜欢集合,您可以明确地进行检查:

list(filter(lambda s: any(item in sublist for sublist in target for item in s), 
            source))

#1


5  

You can use set to check if there is any intersection between elements:

您可以使用set来检查元素之间是否存在任何交集:

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

This could be slightly more efficient if convert the target to a list of sets before hand:

如果先将目标转换为集合列表,这可能会稍微提高效率:

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

When saying lambda, maybe you need a filter function:

说lambda时,也许你需要一个过滤功能:

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

Or in python 3:

或者在python 3中:

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

It seems like your logic is equivalent to the following as @JohnColeman commented:

看起来你的逻辑与@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']]

#2


2  

You can simply use set.difference in the lambda combined with a filter:

您可以简单地在lambda中使用set.difference并结合过滤器:

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

This will keep any list that contains at least one item that is in any of the target-lists.

这将保留包含任何目标列表中的至少一个项目的任何列表。

Or if you don't like sets you can do the checks explicitly:

或者,如果您不喜欢集合,您可以明确地进行检查:

list(filter(lambda s: any(item in sublist for sublist in target for item in s), 
            source))

相关文章