我有两个字典清单。我必须比较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。
答案 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: value
到list
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}]