【问题标题】:Python - Find a word into n lists (without knowing how many are)Python - 在 n 个列表中查找一个单词(不知道有多少)
【发布时间】:2014-12-10 20:04:30
【问题描述】:

作为标题(我搜索了网站但没有找到答案)我必须在n列表中找到一个共同的词。

例如,如果我有这些列表:

list1 = ["a", "b", "c"]
list2 = ["d", "e", "a"]
list3 = ["f", "g", "h", "i", "j"]

list1 和 list2 有一个共同点,即 "a" ... 显然我也可以有 100 个列表……但我不知道数量,当然,算法必须始终有效:P

我想到了一个 for 循环,但我从来没有设法得到具体的东西(在范围 (len (list1)) 中生成 for num),因为如果列表的长度不同,则无法执行任何操作。

编辑:我很抱歉,也许我解释得不好,我没有列表。 我正在处理图表,在图表的节点信息中,我有一个列表,在 cui 中我有信息,我需要找到共享公共信息的节点,以便将它们与弓连接。

在图中我有n 节点,根据它生成程序的方式,因此我有n 列表。

【问题讨论】:

  • 我在list2 中看不到“a”。我仍然不明白你的问题,你是否试图找到所有包含感兴趣元素的列表,例如“一个”?或者找到所有列表的交集?
  • 打扰一下,谷歌翻译已经很好地翻译成哈哈。
  • 附带说明,如果您要拥有 3 到 100 个列表,则它们不应位于名为 list1 到 list100 的单独变量中,它们应位于列表的大列表中 (或者可能是列表的字典)。
  • 为什么会生成数百个单独的列表?基本没用。如果您正在生成输出,请输出一些有用的东西,例如 csv 或 json 之类的......
  • @Ngenator:或者,更一般地说:弄清楚你想用这些信息做什么,询问哪些数据结构会使这些任务变得微不足道,然后这些数据结构就是你应该构建的数据结构。

标签: python algorithm list for-loop


【解决方案1】:

您可以像这样使用集合的交集(如果您有列表列表,请相应地修改)

list1 = ["a", "b", "c", "xc"]
list2 = ["d", "e", "to", "xc"]
list3 = ["f", "g", "h", "i", "j", "xc"]

print list(set(list1) & set(list2) & set(list3)) # it will print ['xc']

【讨论】:

  • 您好,感谢您的回复...我尝试了发布其他用户的各种功能,我想我理解您的功能的行为实际上与@MTrenfield 相同。如果不是为了一个小问题,您的功能很有趣且正确。并不是说所有三个列表(在这种情况下为三个)都必须强制一个共同点......很可能只有两个有一个共同点(如果所有列表都没有共同点,则使用您的代码,它返回给我一个空列表),我应该知道列表的名称。谢谢。
  • @checco94 - 不客气。所以你现在有了进一步进行的想法。请检查您认为可以接受的任何答案,即使您无法投票。
  • 你好,我刚刚投票,但系统说我必须至少有 15 声望才能投票:/ 你太客气了我会投票给你...如果你知道另一种方法这让我知道谢谢。
  • @checco94 - 是的,如果没有信誉积分,仍然可以将答案检查为“已接受”。
  • 你不需要set(list1) & set(list2) & …,你可以使用set(list1).intersection(list2, list3)。另外,为什么要将结果转换回列表?
【解决方案2】:

我问你想要两件事中的哪一个,你回答“完全正确”,然后以一种仍然没有告诉我你想要哪两件事的方式澄清。所以,我仍然不知道您要解决哪个问题。所以我会解释它们。


首先,从您尝试在range(len(list1)) 上循环的事实来看,您可能只在同一位置寻找匹配项——也就是说,list1[3] == list2[3] 是匹配项,但 @987654327 @ 不是。

为此,您通常需要zip 函数。但在这种情况下,鉴于您的评论“如果列表的长度不同,则不能做任何事情”,我假设您想继续直到 longest 列表的末尾。为此,您需要 zip_longest 函数。像这样:

for value1, value2, value3 in itertools.zip_longest(list1, list2, list3):
    if value1 == value2:
        print('found a match')

您很可能会想要检查 listX 与 listY 的所有组合。明智的做法是使用combinations

for values in itertools.zip_longest(list1, list2, list3):
    if any(x == y for x, y in itertools.combinations(values, 2)):
        print('found a match')

这与我在 cmets 中所说的一致:如果您有 3 到 100 个列表,您不希望它们位于单独的变量中,例如 list1list2、...、list100,您想要它们在列表的大列表(或字典)中。


或者,您可能只想将列表视为集合,无论位置如何都可以找到匹配项,因此如果 list1[2] == list2[3] 很重要。

在这种情况下,您所要求的只是集合 intersection 是否为非空。像这样:

if set(list1).intersection(list2, list3):
    print('found a match')

(或者,等效地,您可以 reduce 代替 is_disjoint,或者其他几种方法来做同样的事情。)

但是,如果您想将列表用作集合,则应首先将它们存储为集合。 (同样,您应该将它们存储在一个集合列表中,而不是 3-100 个单独的变量中。)

【讨论】:

    【解决方案3】:

    编写一个函数,该函数接受一个可迭代列表,将它们转换为集合,并获取交集,该交集返回两个集合共有的元素:

    def find_common_words(list_of_lists):
        current_set = set(list_of_lists[0])
        for l in list_of_lists:
            current_set = list_of_lists.intersection(l)
        return list(current_set)
    

    【讨论】:

    • 您好,我为@Timothy Ha 写的评论同样适合您。谢谢你。
    【解决方案4】:
    from itertools import combinations
    
    lists = [
        ["a", "b", "c"],
        ["d", "e", "a"],
        ["f", "g", "h", "i", "j"],
        ["z", "a", "d", "l", "m"]
    ]
    
    for one, two in combinations(lists, 2):
        intersection = list(set(one) & set(two))
        if intersection:
            print one, two, intersection
    

    输出

    ['a', 'b', 'c'] ['d', 'e', 'a'] ['a']
    ['a', 'b', 'c'] ['z', 'a', 'd', 'l', 'm'] ['a']
    ['d', 'e', 'a'] ['z', 'a', 'd', 'l', 'm'] ['a', 'd']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多