【问题标题】:Comparing nested list with dictionary keys, create compound key 'a+b' with sum of values将嵌套列表与字典键进行比较,创建具有值总和的复合键 'a+b'
【发布时间】:2021-06-17 06:57:52
【问题描述】:

我有一个嵌套列表,我想将列表项与字典键进行比较,如果找到匹配项,则应将相应的字典值相加并附加到与新键值对相同​​的字典中。

l1 = [['a','b'], ['c','d']] 

dict1 = {'a':10, 'e':20, 'c':30, 'b':40}

预期结果:

dict1 = {'a':10, 'e':20, 'c':30, 'b':40, 'a+b':50, 'a+c':40, 'b+c':70}

到目前为止我做了什么:

for x in range(len(l1)):
    for y in range(len(l1[x])):
        for k in dict1.keys():
            if k == l1[x][y]:
                dict1.append(dict1[k])

有没有办法在不使用嵌套 for 循环的情况下做到这一点? PS:代码还没写完。

【问题讨论】:

  • 为什么这是您的预期输出?为什么没有,例如c+d?
  • @tomjn 因为字典键中不存在列表项“d”..
  • 对不起,我是愚蠢的,这是有道理的。冒着另一个愚蠢问题的风险,l1 中的子列表有什么特殊含义吗?
  • 您的 l1 似乎错误,嵌套方面无关紧要。我们是否只是应该从 l1 的所有(扁平)元素中获取每个有效的(1-)或 2-元素排列?并忽略像“d”这样的无效键?
  • 原始代码 l1 中的 @smci 被其他一些逻辑附加,子列表有自己的含义。子列表正在其他代码部分中使用。这个想法是比较子列出带有字典键的项目,如果找到匹配项,则添加相应的字典值并附加到同一个字典中(不忽略子列表中不可用的键)我希望现在很清楚

标签: python


【解决方案1】:

假设您的嵌套列表不重要,例如l1 可以改为["a", "b", "c", d"] 你可以在这里使用itertools。

首先将l1 与itertools.chain 展平

import itertools
l2 = itertools.chain(*l1)

(或l2 = itertools.chain.from_iterable(l1))。

然后循环遍历两个元素的所有组合

for i, j in itertools.combinations(l2, 2):
    if i in dict1 and j in dict1:
        dict1[f"{i}+{j}"] = dict1[i] + dict1[j]

大家一起

import itertools 

l1 = [['a','b'], ['c','d']] 
dict1 = {'a':10, 'e':20, 'c':30, 'b':40}
 
for i, j in itertools.combinations(itertools.chain(*l1), 2):
    if i in dict1 and j in dict1:
        dict1[f"{i}+{j}"] = dict1[i] + dict1[j]

dict1 现在等于

{'a': 10, 'e': 20, 'c': 30, 'b': 40, 'a+b': 50, 'a+c': 40, 'b+c': 70}

【讨论】:

  • 感谢您的回答!现在它按预期工作。
  • 问题有一个小的变化..如果嵌套列表包含超过2个元素怎么办..像l1 = [['a','b'], ['c','d'], ['e','f','g']]和dict1 = {'a':10, 'e':20, 'c':30, 'b':40, 'f':10, 'g':20}列表附加了一些逻辑和里面的元素数量嵌套列表不固定..请告诉我在这种情况下如何找到复合键..
  • 嗨@Sourabh,你应该问一个新的后续问题。不清楚您要在此处更改什么以及为什么现有解决方案不起作用?
  • 嗨@tomjn,现有解决方案完美运行.. 但现在我想知道如果子列表元素超过 2 会发生什么.. 例如 l1 就像 l1 = [['a','b'], ['c','d'], ['e','f','g']] 现在预期结果是 @987654336 @ 增加3个元素的逻辑会如何变化?
  • 我认为您应该提出一个新问题,因为我不清楚这里的要求是什么。例如,为什么没有 a+b+c 或 a+b+f 而你有 a+c?
【解决方案2】:

你可以试试下面的代码

dict1 = {'a':10, 'e':20, 'c':30, 'b':40, 'a+b':50, 'a+c':40, 'b+c':70}
dict2={}
dict2['a+b']=dict1['a']+dict1['b']
dict2['a+c']=dict1['a']+dict1['c']
dict2['b+c']=dict1['b']+dict1['c']
dict1.update(dict2)
print(dict1)

【讨论】:

  • 这只是硬接线术语,例如“a+b”。它会在任意输入时中断。
  • 是的,代码是根据o/p的,我发现它很简单,不用循环。
【解决方案3】:

类似下面的东西,使用生成器:

注意:如果您不澄清问题,我将删除此问题

d = {'a':10, 'e':20, 'c':30, 'b':40}
l1 = [['a','b'], ['c','d']]

def _gen_compound_keys(d, kk):
    """Generator helper function for the single and ocmpound keys from input tuple of keys"""
    # Note: you can trivially generalize this from assuming fixed length of 2
    yield kk[0], d[kk[0]]
    yield kk[1], d[kk[1]]
    yield '+'.join(kk), sum(d[k] for k in kk)

def gen_compound_keys(d, kk):
    """Generator for the single and compound keys, returns a dictionary as desired"""
    return {k:v for k,v in _gen_compound_keys(d, kk)}

result = {}
result.update(gen_compound_keys(d, l1[0]))
result.update(gen_compound_keys(d, l1[1]))
result.update(d)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2017-06-21
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    相关资源
    最近更新 更多