python 当缺少键时,如何向列表的字典中添加键值对

92vpleto  于 2023-08-02  发布在  Python
关注(0)|答案(3)|浏览(87)

我有一个disctionary列表,看起来像这样:

list = [{'sitemap': [{'path': 'http://test.com',
                      'errors': '0',
                      'contents': [{'type': 'web',
                                    'submitted': '34801',
                                    'indexed': '4656'}]}]},
        {'sitemap': [{'path': 'https://example.com',
                      'errors': '0',
                      'contents': [{'type': 'web', 'submitted': '2329'}]}]},
        {'sitemap': [{'path': 'https://fakeurl.com', 'errors': '0'}]}]

字符串
某些条目中偶尔缺少“contents”键。
这是我追求的理想输出:

list = [{'sitemap': [{'path': 'http://test.com',
                      'errors': '0',
                      'contents': [{'type': 'web',
                                    'submitted': '34801',
                                    'indexed': '4656'}]}]},
        {'sitemap': [{'path': 'https://example.com',
                      'errors': '0',
                      'contents': [{'type': 'web',
                                    'submitted': '2329',
                                    'indexed': 'NaN'}]}]},
        {'sitemap': [{'path': 'https://fakeurl.com',
                      'errors': '0',
                      'contents': [{'type': 'NaN',
                                    'submitted': 'NaN',
                                    'indexed': 'NaN'}]}]}]


我如何识别'contents'键是否缺失,并在缺失时添加一个值为NaN的键?

o3imoua4

o3imoua41#

循环遍历列表。如果字典中没有contents键,则添加它。
contents存在时,将其与每个键的默认值列表合并。

default_values = {'type': 'NaN', 'submitted': 'NaN', 'indexed': 'NaN'}
for d in list_of_dicts:
    for m in d['sitemap']:
        if 'contents' not in m:
            m['contents'] = [default_values.copy()]
        else:
            for i, old in enumerate(m['contents']):
                m['contents'][i] = default_values | old

字符串

suzh9iv8

suzh9iv82#

您应该遍历'sitemap'中的每个字典,以检查'contents'是否存在。如果它不存在,则创建一个空列表,然后访问列表中的每个字典并填写默认值。如果没有字典,则复制整个默认值并将其追加到列表中:

In [_]: lst = [{'sitemap': [{'path': 'http://test.com',
   ...:           'errors': '0',
   ...:           'contents': [{'type': 'web',
   ...:                         'submitted': '34801',
   ...:                         'indexed': '4656'}]}]},
   ...:        {'sitemap': [{'path': 'https://example.com',
   ...:           'errors': '0',
   ...:           'contents': [{'type': 'web', 'submitted': '2329'}]}]},
   ...:        {'sitemap': [{'path': 'https://fakeurl.com', 'errors': '0'}]}]
   ...:

In [_]: defaults = {'type': 'NaN', 'submitted': 'NaN', 'indexed': 'NaN'}

In [_]: for dct in lst:
   ...:     for sitemap in dct['sitemap']:
   ...:         if contents := sitemap.setdefault('contents', []):
   ...:             for content in contents:
   ...:                 for key, value in defaults.items():
   ...:                     content.setdefault(key, value)
   ...:         else:
   ...:             contents.append(defaults.copy())
   ...:

字符串
输出量:

In [_]: lst
Out[_]:
[{'sitemap': [{'path': 'http://test.com',
    'errors': '0',
    'contents': [{'type': 'web', 'submitted': '34801', 'indexed': '4656'}]}]},
 {'sitemap': [{'path': 'https://example.com',
    'errors': '0',
    'contents': [{'type': 'web', 'submitted': '2329', 'indexed': 'NaN'}]}]},
 {'sitemap': [{'path': 'https://fakeurl.com',
    'errors': '0',
    'contents': [{'type': 'NaN', 'submitted': 'NaN', 'indexed': 'NaN'}]}]}]


如果你想减少一些缩进,你可以使用stdlib中的一些工具:

In [_]: from itertools import chain
   ...: from operator import itemgetter

In [_]: for sitemap in chain.from_iterable(map(itemgetter('sitemap'), lst)):
   ...:     if contents := sitemap.setdefault('contents', []):
   ...:         for content in contents:
   ...:             for key, value in defaults.items():
   ...:                 content.setdefault(key, value)
   ...:     else:
   ...:         contents.append(defaults.copy())
   ...:

wxclj1h5

wxclj1h53#

我认为您可以枚举每个站点Map的“内容”,并在利用setdefault()的同时使用索引进行字典合并

给出:

data = [
    {'sitemap': [{'path': 'http://test.com', 'errors': '0', 'contents': [{'type': 'web', 'submitted': '34801', 'indexed': '4656'}]}]},
    {'sitemap': [{'path': 'https://example.com', 'errors': '0', 'contents': [{'type': 'web', 'submitted': '2329'}]}]},
    {'sitemap': [{'path': 'https://fakeurl.com', 'errors': '0',}]}
]
defaults = {'type': 'NaN', 'submitted': 'NaN', 'indexed': 'NaN'}

字符串

您可以尝试:

for entry in data:
    for sitmap in entry['sitemap']:
        for index, content in enumerate(sitmap.setdefault("contents", [{}])):
            sitmap["contents"][index] = defaults.copy() | content
print(data)


这应该会给予你一些格式:

[
    {'sitemap': [{'path': 'http://test.com', 'errors': '0', 'contents': [{'type': 'web', 'submitted': '34801', 'indexed': '4656'}]}]},
    {'sitemap': [{'path': 'https://example.com', 'errors': '0', 'contents': [{'type': 'web', 'submitted': '2329', 'indexed': 'NaN'}]}]},
    {'sitemap': [{'path': 'https://fakeurl.com', 'errors': '0', 'contents': [{'type': 'NaN', 'submitted': 'NaN', 'indexed': 'NaN'}]}]}
]


不会赢得任何速度比赛,但我认为这是相当容易遵循。

相关问题