<p><a href="https://docs.python.org/3.6/library/collections.html#collections.defaultdict" rel="nofollow noreferrer">^{<cd1>}</a>的这种用法来自<a href="https://stackoverflow.com/a/8702435/833881">this answer</a>,当您试图访问丢失的键时,它会生成一个字典,为丢失的键创建相同类型的字典(正常的<code>dict</code>会引发<code>KeyError</code>)。我假设您可能会看到来自同一IP的多个设备,但没有一个设备会显示多个IP;如果不是后者,这将无法完全按照预期工作。你知道吗</p>
<pre><code>from pprint import pprint
from collections import defaultdict
NestedDict = lambda: defaultdict(NestedDict)
# Catch and parse messages; contrived example
messages = (
{"ip": "1.2.3.4", "device": "BlackBerry", "values": {"temp": 99}},
{"ip": "1.2.3.4", "device": "Android", "values": {"fan_speed": 2}},
{"ip": "1.2.3.4", "device": "BlackBerry", "values": {"temp": 80, "fan_speed": 2}},
{"ip": "9.2.3.9", "device": "MacBook"},
{"ip": "9.2.3.9", "device": "Buick", "values": {"tire_pressure": 35}},
)
devices_by_ip = NestedDict()
for message in messages:
devices_by_ip[message["ip"]][message["device"]].update(message.get("values", {}))
pprint(devices_by_ip)
</code></pre>
<p>编辑为添加:如果包含值<em>的消息没有</em>包含设备名称,则有点不同,我们必须假设每个IP只有一个设备(即,这些消息都不是来自单独网络中的不同设备)。你知道吗</p>
<pre><code>messages = (
{"ip": "1.2.3.4", "device": "BlackBerry"},
{"ip": "1.2.3.4", "values": {"temp": 99}},
{"ip": "2.2.3.4", "values": {"fan_speed": 2}},
{"ip": "2.2.3.4", "device": "Android"},
{"ip": "1.2.3.4", "values": {"temp": 80, "fan_speed": 2}},
)
devices_by_ip = NestedDict()
for message in messages:
if "device" in message:
devices_by_ip[message["ip"]]["device"] = message["device"]
else:
devices_by_ip[message["ip"]].update(message.get("values", {}))
pprint(devices_by_ip)
</code></pre>