【问题标题】:Intersecting nested lists using a lambda function使用 lambda 函数相交嵌套列表
【发布时间】:2017-03-04 02:25:16
【问题描述】:

我想将两个嵌套列表相交:

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 做到这一点?

【问题讨论】:

  • 当你说相交时,你到底是什么意思?您的意思是子列表的一项应该在另一个子列表的一项中?还是应该在“相同”的子列表(相同的索引)中?
  • @MSeifert 是的,子列表的一项应该与另一个子列表的项相同。

标签: python list lambda


【解决方案1】:

你可以使用set来检查元素之间是否有交集:

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

如果事先将 target 转换为集合列表,这可能会更有效:

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

【讨论】:

  • “如果事先将目标转换为集合列表,这可能会更有效”——为什么不通过形成联合将其转换为单个集合?
  • @JohnColeman 啊哈,我觉得你是对的,逻辑好像是这样的。
  • 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]
【解决方案2】:

您可以简单地将set.difference 中的lambda 与过滤器结合使用:

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

这将保留包含至少一项在任何target-lists 中的任何列表。

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

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

【讨论】:

    猜你喜欢
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多