【问题标题】:Iterate through list of dictionories and compare with other dictionories遍历字典列表并与其他字典进行比较
【发布时间】:2021-04-21 11:38:46
【问题描述】:

我有以下词典

dic1 = { 'T1': "HI , china" , 'T2': "HI , finland" ,'T3': "HI , germany"}

dic2 = { 'T1': ['INC1','INC2','INC3'] , 'T2': ['INC2','INC4','INC5'],'T3': ['INC2','INC5']}

dic3 = { 'INC1': {'location':'china'} , 'INC2': {'location':'germany'},'INC3': {'location':'germany'},'INC4': {'location':'finland'}} 

我需要根据 dic1,dic3 删除 dic2 中的值

示例:

  1. 我必须先遍历 dic2 并检查 T1 及其 INC 值。
  2. 如果 Dic1 中对应的 T1 键值与 dic3 中对应的 INC 值匹配,则保留 dic2 中的值,否则弹出该值。

图片中给出了详细的解释。我期待以下输出。

dic2 = { 'T1': ['INC1'] , 'T2': ['INC4'],'T3': ['INC2']}

示例代码:

for k, v in dic2.items():
for k1, v1 in dic1.items():
    if k is k1:
        print k
        for k2 in v:
            for k3 in dic3.items():
  

我是 python 新手。我已经尝试了上面的代码,但我被击倒了。你能帮帮我吗?

【问题讨论】:

    标签: python python-3.x list dictionary


    【解决方案1】:

    可以一次性完成:

    >>> {k: [i for i in v if dic3.get(i, {}).get('location', '#') in dic1[k]] for k, v in dic2.items()}
    {'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
    

    [i for i in v if dic3.get(i, {}).get('location', '#') 是列表推导,如果 dic3[i]['location']dic1[k] 内,则仅从 dic2 的列表中选择值,其中 i 是 dict d3 中的键,k 是来自 dict d2 和 dict d1 的密钥。

    我使用dic3.get(i, {}).get('location', '#')(而不是dic3[i]['location'],你会得到KeyError 用于不在dic3 中的密钥INC5)以避免密钥i 不在dic3 中的问题(将为我的下一个.get 返回一个空的dict,在第二个.get 中,我再次使用它返回location 键的对应值(如果存在)并检查返回的字符串是否位于dict @ 的值内987654342@.

    如果我知道dic3 中不存在密钥i,我返回#(可以是任何字符串/字符)(i 不存在将基本上给出{}.get('location', '#'),而这反过来又会给出#,这肯定会导致d1 的会员资格失败,因此没关系。

    低调的for循环版本:

    >>> ans = {}
    >>> for k, v in dic2.items():
    ...     temp = []
    ...     for i in v:
    ...             if i in dic3 and dic3[i]['location'] in dic1[k]:
    ...                     temp.append(i)
    ...     ans[k] = temp
    ... 
    >>> ans
    {'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
    

    【讨论】:

    • 正确。单线是概率。太dense 在这种情况下很难阅读。也许是另一个版本的for-loop 来展示和比较。干得好。
    【解决方案2】:

    据我了解,您应该修改原始 dic2 字典,而不是为您的答案创建一个新字典,这就是我得到的:

    delete = []
    
    for key, value in dic2.items():
        loc = dic1[key][5:]
        for inc in value:
            if inc not in dic3:
                delete.append(inc)
            else:
                if loc != dic3.get(inc)['location']:
                    delete.append(inc)
    
        for item in delete:
            value.remove(item)
        delete = []
    
    print(dic2)
    
    >>> {'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
    

    第一个 for 循环遍历 dic2 并将所需的位置设置为变量 loc。下一个遍历列表(值)并将它们添加到删除列表中。 在每个循环结束时,它会遍历删除列表,从值列表中删除每个元素,然后将删除设置为空列表。

    我对 python 也比较陌生,所以我确信可能存在效率问题。

    【讨论】:

    • 这也有效..但我只能批准一个。非常感谢您的回复
    【解决方案3】:

    这与其他答案基本相同,但作为单行,它可能更具可读性(也许不是,因为它是主观的)。

    {k: [el] for k, v in dic2.items() for el in v if (el in dic3.keys() and dic3[el]['location'] in dic1[k])}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 2015-10-03
      相关资源
      最近更新 更多