【问题标题】:How to get dictionary key whose value contains at least one item in another list?如何获取其值包含另一个列表中至少一项的字典键?
【发布时间】:2017-09-18 16:36:03
【问题描述】:

我写了一个简单的脚本,其范围是:

list=[1,19,46,28 etc...]
dictionary={Joey:(10,2,6,19), Emily: (0,3), etc}

现在我需要找到字典的所有键,其中至少有一个列表条目的值

示例:Joey 的值是 19,所以 Joey 是赢家。

我是怎么做到的:(根本没有程序员)

# NodesOfSet = the list

# elementsAndTheirNodes = the dictionary

# loop as many times as the number of key:value entries in the dictionary element:nodes
# simply: loop over all the elements
for i in range (0, len (elementsAndTheirNodes.keys())):

    # there is an indent here (otherwise it wouldnt work anyway)
    # loop over the tuple that serves as the value for each key for a given i-th key:value
    # simply: loop over all their nodes
    for j in range (0, len (elementsAndTheirNodes.values()[i])):

        # test: this prints out element + 1 node and so on
        # print (elementsAndTheirNodes.keys()[i], elementsAndTheirNodes.values()[i][j]  )

        for k in range (0, len (NodesOfSet)):
            if NodesOfSet[k] == (elementsAndTheirNodes.values()[i][j]):
                print ( elementsAndTheirNodes.keys()[i], " is the victim")
            else:
                print ( elementsAndTheirNodes.keys()[i], " is not the victim")

但这非常耗时,因为它基本上会迭代数据库中的所有内容。我可以寻求帮助来优化这个吗?谢谢!

【问题讨论】:

  • 只是一个提示:这不是很pythonic -> 列表是一个受保护的单词,所以不要将它用作变量名,变量总是以小写字母开头,“单词”通常是用“_”隔开。也不要在函数和“()”之间放置空格,如 print 或 len 或 range
  • 您好!谢谢你的评论。我不知道在任何地方使用列表这个词。带有大写字母的东西很有趣,尽管不是很有帮助。空格在那里是因为我的文本编辑器在输入时向我提供了已经使用过的单词。
  • 很高兴有人编辑了我的问题以使其更易于理解。但是真的有必要删除我不是程序员吗?谢谢?

标签: python list dictionary key-value


【解决方案1】:

我会使用 list comprehension 和内置的 any,一旦找到共享项就会短路。将您的列表变成一个集合可以将成员查找的复杂性从O(n) 降低到O(1)

s = set(lst)
result = [k for k, v in dct.items() if any(i in s for i in v)]

请注意不要将内置函数指定为对象的名称(例如 list),以避免稍后在代码中使内置函数无法使用。

【讨论】:

    【解决方案2】:

    不要使用名称listlist 是库函数的名称。

    l = [1, 19, 46, 28, ...]
    l_set = set(l)
    
    d = {'Joey':(10,2,6,19), 'Emily': (0,3), ...}
    
    winners = [k for k, v in d.items() if any(i in l_set for i in v)]
    

    any 将在“看到”共享值后立即停止迭代 v,从而节省一些时间。

    【讨论】:

      【解决方案3】:

      您还可以使用 set intersection 来检查字典值元组中的任何元素是否与您的“列表”条目有任何共同之处:

      l = [1,19,46,28, ...]
      s = set(l)
      d = {Joey:(10,2,6,19), Emily: (0,3), ...}
      winners = [k for k, v in d.iteritems() if s.intersection(v)]
      

      【讨论】:

      • if s.intersection(v) 读起来更好,但是您仍然需要构建一个新集合,这可能会或可能不会更快,具体取决于阳性数。
      • @MosesKoledoye 你是对的,但我假设可读性胜过这个问题的效率。既然可以漂亮,为什么还要高效?
      • 而且if len(s.intersection(set(v)))if s.intersection(v)漂亮
      • 啊,这就是你的意思:) 已编辑
      • 是的,你也不需要set(v)set.intersection 需要任何可迭代的:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多