【问题标题】:Python - compare list elements with dictionary elementsPython - 将列表元素与字典元素进行比较
【发布时间】:2017-11-29 13:31:19
【问题描述】:

我有一本字典和一个列表。我需要将字典(整数)的“id”标签与列表元素进行比较。像这样的:

l = [[1], [7], [9]]

dict = {
"first":{
    "id": "0"
},
"second":{
    "id": "7"
},
"third":{
    "id": "4"
}
}

for i in l:
    for j in dict:
        if i == dict[j]["id"]:
            print("Yay!")
        else:
            print("Nay!")

我希望能够检查是否可以在字典的“id”标签中找到列表“l”的任何元素。我怎么做?

【问题讨论】:

  • 你想要的输出是什么?
  • 鉴于l的结构,您需要将str(i[0])id的值进行比较。
  • 附加建议 - 似乎没有特别好的理由将 l 中的每个项目保留在其自己的列表中。如果没有其他代码依赖于它 - 将值保持不变 l = [1,7,9] 会更容易。
  • @chepner 我仍然认为“不”:if str(i[0]) == dict[j]["id"]:
  • @Bilkokuya 你是对的,但在我的完整代码中,append 函数添加了所有类似的元素。

标签: python dictionary compare


【解决方案1】:

我会这样做:

l = [[1], [7], [9]]

dict_ = {
         "first":{"id": "0"},
         "second":{"id": "7"},
         "third":{"id": "4"}
        }

ids = set(int(v['id']) for _, v in dict_.items())  # set of all ids for quick membership testing

l = [sublist for sublist in l if sublist[0] in ids]  # *
print(l)  # -> [[7]]

我假设您想要修改(重新创建)l 列表,其中包含符合您条件的项目。


注意事项:

  1. 不要使用dict 作为变量名。您正在覆盖 Python 内置。
  2. 没有必要拥有一个包含 1 个元素长的子列表的列表。将其展平 (l = [1, 7, 9])

* 或者,如果 l 中的所有元素都是单元素列表,您可以使用以下方法,这很可能会明显更快:

l = list(map(lambda x: [x], ids.intersection(x for y in l for x in y)))

【讨论】:

    【解决方案2】:

    根据其他人的建议,请将 id 作为列表而不是列表。以及filter的解决方案怎么样

    lst_ids = [1, 7, 9]
    
    my_dict = {
    "first":{
        "id": "0"
    },
    "second":{
        "id": "7"
    },
    "third":{
        "id": "4"
    }
    }
    
    filter(lambda k: int(my_dict[k]['id']) in lst_ids, my_dict)
    

    这将返回 ['second'] 匹配的 dict 键。

    【讨论】:

    • 谢谢,但我如何准确地返回名称?我初始化了一个等于过滤器(最后一行)的变量,我得到<filter object at 0x10b083a90>
    • 好的!这可能是在 Python3 中。您可以使用 list(filter(....)) 从过滤器对象中获取列表。
    • 有道理!谢谢!太棒了!
    【解决方案3】:

    你也可以试试这个单行:

    l = [[1], [7], [9]]
    
    d = {"first":{ "id": "0"},
         "second":{"id": "7"},
        "third":{"id": "4"}}
    
    l = [elem for elem in l if elem[0] in list(int(value['id']) for value in d.values())]
    
    print(l)
    

    输出:

    [[7]]
    

    或者您也可以使用filter

    l = [[1], [7], [9]]
    
    d = {"first":{ "id": "0"},
         "second":{"id": "7"},
        "third":{"id": "4"}}
    
    resultValues = list(int(v['id']) for v in d.values())
    l = list(filter(lambda i: i[0] in resultValues, l))
    
    print(l)
    

    输出:

    [[7]]
    

    【讨论】:

      【解决方案4】:

      你可以这样做:

      l = [[1], [7], [9]]
      
      dict = {
               "first":{"id": "0"},
               "second":{"id": "7"},
               "third":{"id": "4"}
              }
      
      for i in l:
          for j in dict:
              if i[0] == int(dict[j]["id"]):
                  print("Yay!")
              else:
                  print("Nay!")
      

      【讨论】:

      • 嗯,我收到一个错误:for j in dict: TypeError: 'type' object is not iterable
      【解决方案5】:

      你可以试试这个:

      l = [[1], [7], [9]]
      
      dict = {
      "first":{
         "id": "0"
       },
      "second":{
       "id": "7"
       },
       "third":{
          "id": "4"
       }
      }
      final_dicts = [{a:b} for a, b in dict.items() if [int(b['id'])] in l]
      print "Yay!" if final_dicts else "Nay"
      

      输出:

      "Yay!"
      

      【讨论】:

      • 确实!耶! ;) 谢谢!
      【解决方案6】:

      何时打印Yay!Nay! -- 转换为int 并签入子列表?

      l = [[1], [7], [9]]
      
      dict1 = {
      "first":{
          "id": "0"
      },
      "second":{
          "id": "7"
      },
      "third":{
          "id": "4"
      }
      }
      
      for i in l:
          for j in dict1:
              if int(dict1[j]['id']) in i:
                  print("Yay!")
              else:
                  print("Nay!")
      

      【讨论】:

      • 这并不是真正的改进。您应该能够通过将元素列表 l 转换为平面列表来摆脱其中一个循环。
      • 这适用于提供的输入。是什么让您认为扁平化列表会改善答案?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多