简体   繁体   English

遍历并删除python词典列表中的某些元素

[英]Iterating through and deleting certain elements in a list of dictionaries in python

I have json file that looks like this: 我有看起来像这样的json文件:

[{'Events': [{'EventName': 'Log',
              'EventType': 'Native',
              'LogLevel': 'error',
              'Message': 'missing event: seqNum=1'},
             {'EventName': 'Log',
              'EventType': 'Native',
              'LogLevel': 'error',
              'Message': 'missing event: seqNum=2'}],
  'Id': 116005},
 {'Events': [{'EventName': 'Log',
              'EventType': 'Native',
              'LogLevel': 'error',
              'Message': 'missing event: seqNum=101'},
             {'EventName': 'Log',
              'EventType': 'Native',
              'LogLevel': 'error',
              'Message': 'missing event: seqNum=102'},
             {'BrowserInfo': {'name': 'IE ', 'version': '11'},
              'EventName': 'Log',
              'EventType': 'Native',
              'LogLevel': 'info',
              'SeqNum': 3,
              'SiteID': 1454445626890,
              'Time': 1454445626891,
              'URL': 'http://test.com'},
             {'BrowserInfo': {'name': 'IE ', 'version': '11'},
              'EventName': 'eventIndicator',
              'EventType': 'responseTime',
              'SeqNum': 8,
              'SiteID': 1454445626890,
              'Time': 1454445626923,
              'URL': 'http://test.com'}],
  'Id': 116005}]

And I am trying to remove each of the events where "EventName": "Log" . 我正在尝试删除其中的每个事件"EventName": "Log"

I would assume there is a way to pop them out, but I can't even iterate far enough into the list to do that. 我认为有一种方法可以将它们pop ,但是我什至无法迭代足够多的位置来做到这一点。 What is the cleanest way to do this? 什么是最干净的方法?

I should end up with a list that looks like: 我应该得到一个看起来像这样的列表:

[{'Events': [{'BrowserInfo': {'name': 'IE ', 'version': '11'},
              'EventName': 'eventIndicator',
              'EventType': 'responseTime',
              'SeqNum': 8,
              'SiteID': 1454445626890,
              'Time': 1454445626923,
              'URL': 'http://test.com'}],
  'Id': 116005}]

It's difficult to modify a list or other data structure as you're iterating over it. 在迭代列表或其他数据结构时,很难进行修改。 It's often easier to create a new data structure, excluding the unwanted values. 创建新的数据结构(排除不需要的值)通常更容易。

You appear to want to do two things: 您似乎想做两件事:

  1. Remove dictionaries from the "Events" lists that have an "EventName" of "Log" . 从字典中删除"Events"列出了有一个"EventName""Log"
  2. Remove any top level dictionaries who's lists of events have become empty after the "Log" events were removed. 删除"Log"事件删除后事件列表变为空的所有顶级词典。

It's a bit tricky to do both at once, I but not too bad: 一次执行这两项操作有点棘手,但我还不错:

filtered_json_list = []
for event_group in json_list:
    filtered_events = [event for event in event_group["Events"]
                             if event["EventName"] != "Log"]
    if filtered_events: # skip empty event groups!
        filtered_json_list.append({"Id": event_group["Id"], "Events": filtered_events})

This was a lot easier than I expected because the top-level dictionaries (which I call event_group s, for lack of a better name) only had two keys, "Id" and "Events" . 这比我预期的要容易得多,因为顶级字典(由于缺少更好的名称,我将其称为event_group )只有两个键: "Id""Events" If instead there were many keys and values in those dictionaries (or which keys and values they had were unpredictable), you'd probably need to replace the last line of my code with something more complicated (eg creating a dictionary with just the filtered events, then using kind of loop to copy over all the non- "Events" keys and values), rather than creating the dictionary by hand with a literal. 相反,如果这些词典中有很多键和值(或者它们中哪些键和值是不可预测的),则您可能需要用更复杂的内容替换我代码的最后一行(例如,创建仅包含过滤事件的字典) ,然后使用某种循环来复制所有非"Events"键和值),而不是用文字手动创建字典。

This program might help. 该程序可能会有所帮助。

import json

# Parse the JSON
with open('x.json') as fp:
    events = json.load(fp)


# Kill all "Log" events
for event_set in events:
    event_list = event_set['Events']
    event_list[:] = [event for event in event_list if event['EventName'] != 'Log']

# Kill all empty event sets
events[:] = [event_set for event_set in events if event_set['Events']]

print json.dumps(events, indent=2)

您可以为此使用Python生成器/列表理解

[x for x in json where x['EventName'] != 'Log']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM