所以我有一个类似这样的学生名单:
students = [ {'name': 'Jack' , 'status' : 'Average' , 'subjects' : { 'subject1' : 'English' , 'subject2' : 'Math' } , 'height' : '20cm' },
{'name': 'Tom' , 'status' : 'Good' , 'subjects' : { 'subject1' : 'English' , 'subject2' : 'Science' } , 'height' : '30cm' }
]
所以上面的列表大小为2.假设尺寸相当大,可以说是50或60或更多。
我想要返回列表 students_output&对于每个学生,我想要返回一个字典,其中包含每个学生的以下值,这些值是从上面的列表中提取的,但稍微修改了一些键'。最终输出应该是这样的:
students_output = [ {'student_name': 'Jack' , 'student_status' : 'Average' , 'student_subjects' : { 'student_subject1' : 'English' , 'student_subject2' : 'Math' } , 'child_height' : '20cm' },
{'student_name': 'Tom' , 'student_status' : 'Good' , 'student_subjects' : { 'student_subject1' : 'English' , 'student_subject2' : 'Science' } , 'child_height' : '30cm' }
]
我无法理解如何创建一个有效的循环,以便我的结果数据结构中的密钥按照输出中的提供进行维护,我可以从第一个列表中获取数据。
例如,在students_output中,我知道
students_output[0]['student_name']=students[0]['name']
但是,任何人都可以帮助我反复进行吗?
答案 0 :(得分:1)
为了实现这一点,您必须在每个键的开头连接"student_"
,并将"height"
键作为一个例外。您可以通过列表理解和 dict理解表达式的组合来实现:
students = [
{'name': 'Jack' , 'status' : 'Average' , 'subjects' : { 'subject1' : 'English' , 'subject2' : 'Math' } , 'height' : '20cm' },
{'name': 'Tom' , 'status' : 'Good' , 'subjects' : { 'subject1' : 'English' , 'subject2' : 'Science' } , 'height' : '30cm' }
]
def get_key(key):
return {
'height': 'child_height', # All exception you need in `key`
# apart from concatenating `"student_"`
}.get(key, 'student_' + key)
new_list = [{
get_key(k): ({
get_key(kk):v for kk, vv in v.items()} if isinstance(v, dict) else v) \
for k, v in s.items()
} for s in students]
new_list
保留的值为:
[{'student_name': 'Jack', 'child_height': '20cm', 'student_status': 'Average', 'student_subjects': {'student_subject1': {'subject1': 'English', 'subject2': 'Math'}, 'student_subject2': {'subject1': 'English', 'subject2': 'Math'}}},
{'student_name': 'Tom', 'child_height': '30cm', 'student_status': 'Good', 'student_subjects': {'student_subject1': {'subject1': 'English', 'subject2': 'Science'}, 'student_subject2': {'subject1': 'English', 'subject2': 'Science'}}}]
答案 1 :(得分:0)
这是一个快速而肮脏的功能,可以满足您的需求:
In [10]: def rename_keys(students):
...: d = {}
...: for k,v in students.items():
...: if isinstance(v,dict):
...: k = "student_" + k
...: v = rename_keys(v)
...: d[k] = v
...: elif k == 'height':
...: k = "child_height"
...: d[k] = v
...: else:
...: k = "student_" + k
...: d[k] = v
...: return d
...:
...:
In [11]: [rename_keys(d) for d in students]
Out[11]:
[{'child_height': '20cm',
'student_name': 'Jack',
'student_status': 'Average',
'student_subjects': {'student_subject1': 'English',
'student_subject2': 'Math'}},
{'child_height': '30cm',
'student_name': 'Tom',
'student_status': 'Good',
'student_subjects': {'student_subject1': 'English',
'student_subject2': 'Science'}}]
实际上,这不一定是递归的,你可以用字典理解来代替递归调用:
v = {'student_'+key:value for key,value in v.items()}
答案 2 :(得分:-1)
您可以在列表推导中使用以下函数,如下所示:
def new_dict(d):
res = {}
for key, value in d.iteritems():
student_or_child = 'student' if key != 'height' else 'child'
if type(value) == dict:
res['{}_{}'.format(student_or_child, key)] = new_dict(value)
else:
res['{}_{}'.format(student_or_child, key)] = value
return res
上面的函数将dict作为参数,对于传递的key, value
中的每个dict
,如果值是dict类型,则在值上调用相同的函数,并将结果添加到{ {1}} dict,否则会添加相同的值。
现在,使用list comprehension
,我们可以:
res
<强>输出:强>
[new_dict(d) for d in students]