我试图访问字典中键的嵌套元素,但每次尝试遍历它们时都被挂断了。
我尝试将字典变平并尝试对元素进行各种索引访问,但没有成功。
目标:访问各个元素,例如:
print(flat['_items'][0]['items']['timestamp'])
print(flat['_items'][0]['items']['value'])
以下是我尝试访问的代码、数据和元素。
def flatten_dict(dd, separator='_', prefix=''):
return { prefix + separator + k if prefix else k : v
for kk, vv in dd.items()
for k, v in flatten_dict(vv, separator, kk).items()
} if isinstance(dd, dict) else { prefix : dd }
# Attempt to Flatten the Dictinary
flat = flatten_dict(regDataDict)
for k in flat.keys():
print(k)
for k, v in flat.items():
print(k, v)
print(flat['_items'][0]['items']['timestamp']) # TypeError: string indices must be integers
print(flat['_items'][0]) # Prints all Dictionary Keys and Values
print(flat['_items']) # Prints all Dictionary Keys and Values
print(flat['_items']['{items}']) # TypeError: string indices must be integers
字典结构
_items = [
{'items': [{'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:40:00Z',
'value': -180.625427,
'web_exception': None}],
'links': {'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegw8PMMAA'},
'web_id': 'I1DPOGpIXSBWLkGcEkjIvyMegw8PMMAA'},
{'items': [{'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:40:00Z',
'value': 59.99268,
'web_exception': None}],
'links': {'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegw7_MMAA'},
'web_id': 'I1DPOGpIXSBWLkGcEkjIvyMegw7_MMAA'},
{'items': [{'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:39:56.055191Z',
'value': 304.8489,
'web_exception': None}],
'links': {'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegwuMYIAA'},
'web_id': 'I1DPOGpIXSBWLkGcEkjIvyMegwuMYIAA'}
]
答案 0 :(得分:1)
您的直接问题是您的索引与您的结构不匹配。 items
是一个包含字典的列表,而不是字典本身。正确的访问顺序是
print(regDataDict[0]['items'][0]['timestamp'])
打印什么
2021-02-01T21:40:00Z
长期的问题是你说你正在尝试扁平化你的字典,但是:
如果您出于某种原因需要扁平化结构,那么我们需要您指定结果数据结构,并跟踪您的代码到问题点。
特别是,我观察到您习惯将 dict 作为列表的唯一元素。这似乎没有提供组织上的好处。如果不出意外,您的数据清理可能应该摆脱这个额外的级别。
答案 1 :(得分:0)
OP,作为对 Prune 答案的补充,我是否可以为您的数据建议一种替代结构,其中 web_id
成为键并且关联的数据是内部字典:
_items = {
'I1DPOGpIXSBWLkGcEkjIvyMegw8PMMAA': {
'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:40:00Z',
'value': -180.625427,
'web_exception': None,
'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegw8PMMAA'
},
'I1DPOGpIXSBWLkGcEkjIvyMegw7_MMAA': {
'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:40:00Z',
'value': 59.99268,
'web_exception': None,
'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegw7_MMAA'
},
'I1DPOGpIXSBWLkGcEkjIvyMegwuMYIAA': {
'errors': None,
'good': True,
'questionable': False,
'substituted': False,
'timestamp': '2021-02-01T21:40:00Z',
'value': 304.8489,
'web_exception': None,
'source': 'https://I1DPOGpIXSBWLkGcEkjIvyMegwuMYIAA'
}
}
我真的不知道你在做什么,我假设 web_id
对于每个对象都是唯一的(否则,使用 _id
会产生误导!),我只是想我会把它扔掉,因为它会更容易使用。
假设您的输入数据结构一致,您可以如何进行数据清理:
new_items = {}
for d in _items:
new_items[d['web_id']] = {**d['items'][0]}
new_items[d['web_id']]['source'] = d['links']['source']
如果您想要更干净的键,您还可以从 web_id
中去除公共子字符串:
new_items = {}
for d in _items:
new_id = d['web_id'].replace('I1DPOGpIXSBWLkGcEkjIvyMeg', '')
new_items[new_id] = {**d['items'][0]}
new_items[new_id]['source'] = d['links']['source']
答案 2 :(得分:0)
谢谢大家
我修改了我的方法,让我感觉更面向对象并避免了很多不必要的字典和列表操作。
我从 Kien Nguyen Trung 的精彩帖子中借用了类结构:https://kiennt.com/blog/2012/06/14/python-object-and-dictionary-convertion.html
class PiStruct(object):
def __init__(self, **entries):
self.__dict__.update(entries)
# convert to PI Response "Class" to Dictionary
regDataDict = piItemsStreamValuesR.__dict__
# convert the Dictionary to a Class
classMembers = PiStruct(**regDataDict)
# Print the Class Members
for i in range(0,len(classMembers._items)):
for n in range(0,len(classMembers._items[i].items)):
print('Timestamp:', classMembers._items[i].items[i].timestamp)
print('Reading:', classMembers._items[i].items[i].value)
print('Name:', classMembers._items[i].name)
原始 PI 对象类型:
Timestamp: 2021-02-02T16:42:00Z
Reading: 145.6539
Name: Sample Name
Timestamp: 2021-02-02T16:42:00Z
Reading: 59.9942245
Name: Sample Name
Timestamp: 2021-02-02T16:41:20.4717254Z
Reading: -189.0652
Name: Sample Name