[英]Accessing Elements of a Deeply Nested Python Dictionary
我正在嘗試訪問字典中鍵的嵌套元素,但每次嘗試遍歷它們時都會掛斷。
我試圖展平字典並嘗試對元素進行各種索引訪問器,但沒有運氣。
目標:訪問各個元素,例如:
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'}
]
您的直接問題是您的索引與您的結構不匹配。 items
是一個包含字典的列表,而不是字典本身。 正確的訪問順序是
print(regDataDict[0]['items'][0]['timestamp'])
哪個打印
2021-02-01T21:40:00Z
長期的問題是你說你正在嘗試扁平化你的聽寫,但是:
如果您出於某種原因需要展平結構,那么我們需要您指定生成的數據結構,並將您的代碼跟蹤到問題點。
特別是,我觀察到您習慣將 dict 作為列表的唯一元素括起來。 這似乎沒有提供任何組織利益。 如果不出意外,您的數據清理可能應該擺脫這個額外的級別。
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'
}
}
我真的不知道您在做什么,並且我假設每個 object 的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
中刪除常見的 substring:
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']
感謝大家,
我修改了我的方法,使其感覺更加面向對象,並避免了很多不必要的字典和列表操作。
我從 Kien Nguyen Trung 的精彩帖子中借用了 Class 結構: https://kiennt.com/blog/2012/06/14/python-object-and-dictionary-convertion.ZFC356EZ83A
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 Object 類型:<class 'osisoft.pidevclub.piwebapi.models.pi_items_stream_values.PIItemsStreamValues'>
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.