我是Python的新手,如果有人回答
,我将不胜感激我有以下字典列表
{'body': 'text'},
{'correctAnswer': 'text'},
{'ans': 'text'},
{'ans': 'text'}
所需的输出是:
{'body': 'text', 'correctAnswer': 'text','ans_1': 'text', 'ans_2': 'text'}
如何用所需的顺序替换键和值
答案 0 :(得分:-1)
L = [{'body': 'text'},
{'correctAnswer': 'text'},
{'ans': 'text'},
{'ans': 'text'},
{'ans': 'text'}]
def key_startswith(new_key, new_value, old_d):
keys_lst = list(old_d.keys())
# check if there's a key that startswith the new_key
if any(key.startswith(new_key) for key in keys_lst):
# check if this key is exactly the same as the new key
if any(key == new_key for key in keys_lst):
old_d[new_key+"_1"] = old_d.pop(new_key)
old_d[new_key+"_2"] = new_value
# if not exactly the same, add key + "_" + num
else:
all_matches = [key for key in keys_lst if key.startswith(new_key)]
splitted = [int(el.split("_")[-1]) for el in all_matches]
new_number = max(splitted) + 1
old_d[new_key+"_"+str(new_number)] = new_value
else:
old_d[new_key] = new_value
return old_d
def zip_all_dicts(lst):
output = {}
for el in lst:
if isinstance(el, dict):
for k,v in el.items():
output = key_startswith(k,v,output)
# if not dict
else:
continue
return output
zip_all_dicts(L)
也许不是最漂亮但易于理解且有效。
运行zip_all_dicts(L)
会产生:
{'ans_1': 'text',
'ans_2': 'text',
'ans_3': 'text',
'body': 'text',
'correctAnswer': 'text'}
答案 1 :(得分:-1)
您可以使用更新方法实现此目的。
如果您有以下名为:
的词典dict1 = {'body': 'text'}
dict2 = {'correctAnswer': 'text'}
dict3 = {'ans': 'text'}
dict4 = {'ans': 'text'}
然后通过以下操作将获得所需的:
d0 = dict1.copy()
d0.update(dict2)
d0.update(dict3)
d0.update(dict4)
print(d0)#will contain all 4 dicts
如果您有一个dicts数组并且需要迭代,您可以想象如何使用循环执行此操作。
编辑: 刚看到你想要不同的钥匙。您可以在每次更新之前执行以下操作以进行检查:
countDict = {}
key = 'ans'
if key in countDict:
i = countDict[key]
countDict[key] = i+1
key+str(i)
else:
countDict[key] = 0
d0[key] = 'text'
答案 2 :(得分:-1)
您可以使用itertools.groupby
:
from itertools import groupby
lst = [{'body': 'text'}, {'correctAnswer': 'text'}, {'ans': 'text'},
{'ans': 'text'}]
lst.sort(key=lambda x: list(x)[0])
d = {}
for k, g in groupby(lst, key=lambda x: list(x)[0]):
l = list(g)
if len(l) > 1:
for i, v in enumerate(l, 1):
d["{}_{}".format(k, i)] = list(v.values())[0]
else:
d[k] = list(l[0].values())[0]
print(d) # {'body': 'text', 'correctAnswer': 'text', 'ans_1': 'text', 'ans_2': 'text'}
答案 3 :(得分:-1)
你可以试试这个:
import itertools, re
s = [{'body': 'text'}, {'correctAnswer': 'text'}, {'ans': 'text'}, {'ans': 'text'}]
new_data = list(itertools.chain.from_iterable([i.items() for i in s]))
final_data = [(a, list(b)) for a, b in itertools.groupby(sorted(new_data), key=lambda x:x[0])]
possibilies = [(a, [i[-1] for i in b]) for a, b in final_data]
final_dict = {}
for key, value in possibilies:
for i, a in enumerate(value, start = 1):
final_dict["{}_{}".format(key, i)] = a
new_final_dict = {a[:a.index('_')] if [c[:c.index('_')] for c in final_dict].count(a[:a.index('_')]) == 1 else a:b for a, b in final_dict.items()}
sort_key = ['body', 'correctAnswer', 'ans_1', 'ans_2']
final_data = sorted(new_final_dict.items(), key=lambda x:sort_key.index(x[0]) if not x[0][-1].isdigit() else int(re.findall('\d+$', x[0])[0]))
print(final_data)
输出:
[('body', 'text'), ('correctAnswer', 'text'), ('ans_1', 'text'), ('ans_2', 'text')]
使用collections.OrderedDict
:
from collections import OrderedDict
d = OrderedDict()
sort_key = ['body', 'correctAnswer', 'ans_1', 'ans_2']
final_data = sorted(new_final_dict.items(), key=lambda x:sort_key.index(x[0]) if not x[0][-1].isdigit() else int(re.findall('\d+$', x[0])[0]))
for a, b in final_data:
d[a] = b
print(d)
输出:
OrderedDict([('body', 'text'), ('correctAnswer', 'text'), ('ans_1', 'text'), ('ans_2', 'text')])
OrderedDict
将允许您按所需的排序顺序查看字典的包含,并且还允许您像通常的字典一样按键访问值。