【问题标题】:Accessing different JSON key/value pairs in a list comprehension在列表理解中访问不同的 JSON 键/值对
【发布时间】:2018-12-18 18:36:06
【问题描述】:

不确定我是否正在尝试实现不可能的目标?我有这个 JSON 字符串:

dot= [{"type": 1, "date": "2018-12-02T00:40:03.2186792+00:00", "device": 
[{"id": "20165cf4e596", "deviceName": "17", "records": [{"timestamp": "2018- 
12-02T00:40:00.499+00:00", "grp": "undefined", "val": 887}]}, {"id": 
"5f401a6a6f66", "deviceName": "18", "records": [{"timestamp": "2018-12- 
02T00:42:00.499+00:00", "grp": "undefined", "val": 1063}, {"timestamp": 
"2018-12-02T00:41:00.498+00:00", "grp": "undefined", "val": 907}]}, {"id": 
"569bb0147a72", "deviceName": "19", "records": [{"timestamp": "2018-12- 
02T00:44:00.499+00:00", "grp": "undefined", "val": 817}, {"timestamp": 
"2018-12-02T00:43:00.498+00:00", "grp": "undefined", "val": 1383}]}, {"id": 
"ef829aa3", "deviceName": "2", "records": [{"timestamp": "2018-12- 
02T00:46:00.499+00:00", "grp": "undefined", "val": 1173}]}, {"id": 
"388ae8f2fa64", "deviceName": "17", "records": [{"timestamp": "2018-12- 
02T00:41:00.499+00:00", "grp": "undefined", "val": 866}, {"timestamp": 
"2018-12-02T00:32:00.492+00:00", "grp": "undefined", "val": 1080}]}, {"id": 
"01f874b30b55", "deviceName": "19", "records": [{"timestamp": "2018-12- 
02T00:43:00.499+00:00", "grp": "undefined", "val": 1050}, {"timestamp": 
"2018-12-02T00:42:00.498+00:00", "grp": "undefined", "val": 1084}]}]}]

我想实现以下目标:

[{'id': '20165cf4e596','deviceName': '17','timestamp': '2018-12- 
02T00:40:00.499+00:00','grp': 'undefined','val': 887},
{'id': '5f401a6a6f66','deviceName': '18','timestamp': '2018-12- 
02T00:42:00.499+00:00','grp': 'undefined','val': 1063},
{'id': '5f401a6a6f66','deviceName': '18','timestamp': '2018-12- 
02T00:41:00.498+00:00','grp': 'undefined','val': 907},...]

我使用了以下代码:

for i in dot:
    for k in i['device']:
        d2= [[{l:m},{'value':v}] for l,m in k.items() for p in m if 
        isinstance(p,list) for v in p]
        print(d2)

得到了空列表:

[]
[]
[]
[]

提前致谢

【问题讨论】:

  • 检查为什么if isinstance(p,list)总是假的;可能通过将您的理解展开为经典循环
  • 另外:您的输入数据在字符串中有换行符,因此没有人可以按原样复制/粘贴进行测试。请更正这一点。
  • 谢谢@Jean-FrançoisFabre 不确定您的意思。不过好像已经解决了。谢谢

标签: python json python-3.x dictionary nested


【解决方案1】:

您需要遍历每个设备的records 元素。然后将设备中的字段与每条记录结合起来。

result = []
for i in dot:
    for k in i['device']:
        for r in k['records']:
            result.append({"id": k["id"], "deviceName": k["deviceName"], "timestamp": r["timestamp"], "grp": r["grp"], "val": r["val"]})
print(result)

【讨论】:

  • 感谢@Barmar,它很有效。我在看一些太复杂的东西。感谢您的简化。干杯
【解决方案2】:

Barmar's answer 可能是正确的 - 但我相信,如果您通过创建代表数据结构中项目的对象层次结构来对代码进行去混淆处理,您将会轻松得多:

class SomeObject:
    def __init__(self, some_object_type, date, devices):
        self.type = some_object_type
        self.date = date
        self.devices = []

        for d in devices:
            some_device = SomeDevice(d["id"], d["deviceName"], d["records"])
            self.devices.append(some_device)

class SomeDevice:
    def __init__(self, some_device_id, name, records):
        self.id = some_device_id
        self.name = name
        self.records = []

        for r in records:
            some_record = SomeDeviceRecord(r["timestamp"], r["grp"], r["val"])
            self.records.append(some_record)

class SomeDeviceRecord:
    def __init__(self, timestamp, group, value):
        self.timestamp = timestamp
        self.group = group
        self.value = value

如果你走这条路,你可以很容易地将整个 JSON 解析成强类型对象:

some_object = SomeObject(dot[0]["type"], dot[0]["date"], dot[0]["device"])

然后报告数据结构的特定部分应该相当容易/直接:

for device in some_object.devices:
    print(device.id, device.name, device.records[0].timestamp, device.records[0].group, device.records[0].value)

【讨论】:

  • 感谢@alex,是的,同意,这可以完全控制 JSON 的所有元素。我添加了“{}”来对相关值进行分组。有没有办法可以对值进行排序,以便我可以转换为 DataFrame? [{'17', '20165cf4e596', '2018-12-02T00:40:00.499+00:00', 887, '未定义'}, {1063, '18', '2018-12-02T00:42:00.499 +00:00', '5f401a6a6f66', '未定义'}, {'19', '2018-12-02T00:44:00.499+00:00', '569bb0147a72', 817, '未定义'}]
  • 是的。我不知道,但您可能可以在some_object.devices 上使用sorted() 和lambdas。
  • 谢谢@alex,一定会试一试的。非常感谢!
  • 我认为最终的目标是把它变成类似 CSV 的东西,这就是扁平化所有东西的关键。
  • @Barmar 完全合理:)
猜你喜欢
  • 2019-06-15
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多