更新嵌套字典中的键,但键字符串中有一些例外

2024-04-26 01:13:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一张学生名单,看起来像这样:

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 = [ {'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[0]['student_name']=students[0]['name']

但是有人能帮我迭代吗?你知道吗


Tags: name列表englishstatusmathstudent学生average
3条回答

您可以在列表中使用以下函数:

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作为参数,对于传递的dict中的每个key, value,如果value的类型是dict,则对value调用相同的函数,并将结果添加到resdict,否则添加相同的值。你知道吗

现在,使用^{},我们可以:

[new_dict(d) for d in students]

输出:

>>> [new_dict(d) for d in students]
[{'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'}}]

为了实现这一点,您必须在每个键的开头连接"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'}}}]

下面是一个快速而肮脏的函数,它可以满足您的需要:

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()}

相关问题 更多 >