使用列表推导来连接相关词典

时间:2017-10-10 21:53:55

标签: python

我的目标是构建一个列表,该列表使用第一个字典的键(IDENTITY)和第二个字典(DATA)中的值。

我试图按位置连接值(来自DATA)以形成单个列表。 IDENTITY的值决定将哪些DATA值分配给IDENTITY中的键。

例如,在IDENTITY中,键“0001”具有“Alpha”和“Bravo”。在DATA中,'Alpha'和'Bravo都是指定的列表。目标是连接两个列表,以便我们得到一个与原始列表长度相同的列表。希望下面的例子更清楚。

IDENTITY字典:

IDENTITY = {
            '0001': ['Alpha', 'Bravo'],              
            '0011': ['Alpha', 'Charlie'],
            '0111': ['Charlie', 'Bravo']
           }

数据字典:

DATA = {
        'Alpha': ['A', 'B', 'X'],
        'Bravo': ['B', 'C', 'Y'],
        'Charlie': ['C', 'D', 'Z']
       }

输出结果如下:

OUTPUT = [
          ['0001', 'AB', 'BC', 'XY'],
          ['0011', 'AC', 'BD', 'XZ'],
          ['0111', 'CB', 'DC', 'ZY']
         ]

我所知道的:

假设我有以下两个词典:

a = {'A': [1,2,3,4]}
b = {1: [5,5,5,5,5], 2: [6,6,6,6,6], 3: [7,7,7,7,7], 4:[8,8,8,8,8]}

我能做到:

print b[a['A'][0]]

,输出为:

[5, 5, 5, 5, 5]

我可能错了,但我认为我可以将其纳入列表理解中,从而产生所需的输出。

问题

我的问题是你如何在列表理解中做到这一点,或者甚至可以用当前的设置?我应该将其中一个词典更改为列表列表吗?

修改

到目前为止的回复:

列表理解是否采用了错误的方法?

3 个答案:

答案 0 :(得分:1)

我想我终于明白你所追求的是什么以及如何通过列表理解来实现...只需要我午睡。 ;¬)抱歉这么密集。

def makelist(identity, data):
    return [[id]+[''.join(ch) for ch in zip(*[data[label] for label in labels])]
                for id, labels in identity.items()]

IDENTITY = {
    '0001': ['Alpha', 'Bravo'],
    '0011': ['Alpha', 'Charlie'],
    '0111': ['Charlie', 'Bravo']
}

DATA = {
    'Alpha': ['A', 'B'],
    'Bravo': ['B', 'C'],
    'Charlie': ['C', 'D']
}

print(makelist(IDENTITY, DATA))

输出:

[['0001', 'AB', 'BC'], ['0011', 'AC', 'BD'], ['0111', 'CB', 'DC']]

注意:返回列表中项目的顺序是不可预测的,因为它是由identity字典参数的有效无序键确定的。

答案 1 :(得分:0)

修改

哎呀,我没有意识到你想要你的个人信件的转置。这变得有点复杂,但使用zip函数很容易实现。虽然,我永远不会使用列表理解为不可读的:

In [18]: [[k,*(''.join(x) for x in zip(*(DATA[l] for l in v)))] for k,v in IDENTITY.items()]
Out[18]: [['0001', 'AB', 'BC'], ['0011', 'AC', 'BD'], ['0111', 'CB', 'DC']]

原始答案

是的,这是可能的,迭代.items中的IDENTITY并加入DATA的映射结果:

In [4]: OUTPUT = [[k,*(''.join(DATA[l]) for l in v)] for k,v in IDENTITY.items()]

In [5]: OUTPUT
Out[5]: [['0001', 'AB', 'BC'], ['0011', 'AB', 'CD'], ['0111', 'CD', 'BC']]

注意,我使用了漂亮的*解包,但您也可以执行以下操作:

In [6]: OUTPUT = [[k]+[''.join(DATA[l]) for l in v] for k,v in IDENTITY.items()]

In [7]: OUTPUT
Out[7]: [['0001', 'AB', 'BC'], ['0011', 'AB', 'CD'], ['0111', 'CD', 'BC']]

答案 2 :(得分:0)

您可以根据需要在一行中找到解决方案:

from collections import defaultdict


IDENTITY = {
            '0001': ['Alpha', 'Bravo'],
            '0011': ['Alpha', 'Charlie'],
            '0111': ['Charlie', 'Bravo']
           }

DATA = {
        'Alpha': ['A', 'B'],
        'Bravo': ['B', 'C'],
        'Charlie': ['C', 'D']
       }

final_dict={}

one_line=[final_dict.setdefault(item, []).append("".join(item_2)) for item,value in IDENTITY.items() for item_3 in value for item_1, item_2 in DATA.items() if item_3 == item_1]

print(final_dict)

输出:

{'0111': ['CD', 'BC'], '0011': ['AB', 'CD'], '0001': ['AB', 'BC']}
  

其他信息:

详细解决方案:

final_dict={}
for item,value in IDENTITY.items():
    for item_3 in value:
        for item_1, item_2 in DATA.items():
            if item_3 == item_1:

                final_dict.setdefault(item, []).append("".join(item_2))


print(final_dict)