比较两个字典列表,并将值附加到另一个列表

时间:2018-09-10 00:48:56

标签: python python-3.x

我有两个字典清单。我必须比较trans中的CodeDesc和code_tbl中的code_desc,如果有匹配项,则将code_tbl中的代码添加到trans中。

trans = [{'id': 12345, 'Name': 'John Smith', 'CodeDesc': 'XYZ'},
         {'id': 67891, 'Name': 'Jane Smith', 'CodeDesc': 'ABC'}]

code_tbl = [{'code': 98, 'code_desc': 'XYZ'},
            {'code': 76, 'code_desc': 'ABC'}]

我的意图是拥有这样的东西:

trans = [{'Id': 12345, 'Name': 'John Smith', 'CodeDesc': 'XYZ', 'Code': 98},
         {'Id': 67891, 'Name': 'Jane Smith', 'CodeDesc': 'ABC', 'Code': 76}]

最终,根据条件,来自trans的数据将被写入Excel文件的不同选项卡。

这是我的代码,出现错误“ TypeError:字符串索引必须是整数”

for t in trans:
#print(t['CodeDesc'])
    for c in code_tbl:
        #print([c['code_desc'])
        if t['CodeDesc'] == c['code_desc']:
             trans.append(c['code'])

我在做什么错,以及如何解决?当我打印t ['CodeDesc']和c ['code_desc']时,它正在打印所有代码描述。

任何帮助将不胜感激。我是python的新手。使用XLSWRITER编写Excelfile。

5 个答案:

答案 0 :(得分:1)

您应该在要更新匹配字典时添加到要迭代的列表中。使用dict.update代替list.append

if t['CodeDesc'] == c['code_desc']:
    t.update(Code=c['code'])

print (trans)
[{'Code': 98, 'CodeDesc': 'XYZ', 'Name': 'John Smith', 'id': 12345},
 {'Code': 76, 'CodeDesc': 'ABC', 'Name': 'Jane Smith', 'id': 67891}]

或者,您可以通过一次通过生成dict映射,然后通过另一次通过进行更新。这应该是一个线性解决方案。

mapping = {c['code_desc'] : c['code'] for c in code_tbl}
for t in trans:
    t.update(Code=mapping.get(t['CodeDesc']))

print (trans)
[{'Code': 98, 'CodeDesc': 'XYZ', 'Name': 'John Smith', 'id': 12345},
 {'Code': 76, 'CodeDesc': 'ABC', 'Name': 'Jane Smith', 'id': 67891}]

最后,如果您有熊猫,我建议您使用merge

import pandas as pd
v = (pd.DataFrame(trans)
       .merge(pd.DataFrame(code_tbl), left_on='CodeDesc', right_on='code_desc') 
       .drop('code_desc', 1))

print (v.to_dict('r'))    
[{'CodeDesc': 'XYZ', 'Name': 'John Smith', 'id': 12345, 'code': 98}, 
 {'CodeDesc': 'ABC', 'Name': 'Jane Smith', 'id': 67891, 'code': 76}]

答案 1 :(得分:0)

您收到此错误,是因为您在遍历Trans时正在修改trans。基本上,您会附加一个{int} c['code'],然后您的循环将尝试在该int上运行。

答案 2 :(得分:0)

对于这种特殊情况,您可以使用list comprehension使用一种线性语法来解决它:

output = [
    {
       'Id': elm.get('id'),
       'Name': elm.get('Name'),
       'CodeDesc': elm.get('CodeDesc'),
       'code': k.get('code')
    } for elm in trans for k in code_tbl if k.get('code_desc') == elm.get('CodeDesc')
]

print(output)

输出:

[{'Id': 12345, 'Name': 'John Smith', 'CodeDesc': 'XYZ', 'code': 98},
 {'Id': 67891, 'Name': 'Jane Smith', 'CodeDesc': 'ABC', 'code': 76}]

答案 3 :(得分:0)

解决方案

import pprint

trans = [ 
    {'id': 12345, 'Name': 'John Smith', 'CodeDesc': 'XYZ'},
    {'id': 67891, 'Name': 'Jane Smith', 'CodeDesc': 'ABC'}
]

code_tbl = [ 
    {'code': 98, 'code_desc': 'XYZ'}, {'code': 76, 'code_desc': 'ABC'}
]

for i in trans:
    for j in code_tbl:
        if i['CodeDesc'] == j['code_desc']:
            i['Code'] = j['code']

pprint.pprint(trans)

输出

(xenial)vash@localhost:~/python/AtBS$ python3.7 trans_code.py 
[{'Code': 98, 'CodeDesc': 'XYZ', 'Name': 'John Smith', 'id': 12345},
 {'Code': 76, 'CodeDesc': 'ABC', 'Name': 'Jane Smith', 'id': 67891}]

如果您查看它,trans[0]trans[1]都是没有key Code的字典,因此您不希望附加新的{ key: valuelist trans

中的每个字典

答案 4 :(得分:0)

这对我来说很完美。

for i, (dict1, dict2) in enumerate(zip(trans, code_tbl)):
    if dict1['CodeDesc'] == dict2['code_desc']:
        trans[i].update({'code':dict2['code']})

输出显示在下面:

print(trans)

[{'id': 12345, 'Name': 'John Smith', 'CodeDesc': 'XYZ', 'code': 98},
 {'id': 67891, 'Name': 'Jane Smith', 'CodeDesc': 'ABC', 'code': 76}]