如何删除具有空值的字典键?

时间:2021-04-21 14:52:55

标签: python python-3.x dictionary

目前,我正在编写一个脚本 (3.9),它接受一个 .csv 文件,并从中创建一个 .json 文件。原代码如下...

import csv
import json
from time import time

start = time()


def make_json(csv_path, json_path):
    data = []

    with open(csv_path, encoding='utf-8') as csvp:
        csv_reader = csv.DictReader(csvp)

        for row in csv_reader:
            data.append(row)

    with open(json_path, 'w', encoding='utf-8') as jsonp:
        jsonp.write(json.dumps(data, indent=4))


csv_path = r'elearningtest.csv'
json_path = r'elearningtest.json'

make_json(csv_path, json_path)

print(f'Time taken to run: {time() - start} seconds')

这里按预期工作。这是输出示例...

[
    {
        "username": "username0001",
        "course_code": "coursecode_001",
        "enrollment_date": "7/28/2015 16:16",
        "completion_date": "8/28/2019 11:20",
        "score": ""
    },
    {
        "username": "username0002",
        "course_code": "coursecode_001",
        "enrollment_date": "7/28/2015 16:18",
        "completion_date": "8/7/2019 17:20",
        "score": "78"
    },
    {
        "username": "username0003",

但是,我想要的是以下内容:

[
    {
        "username": "username0001",
        "course_code": "coursecode_001",
        "enrollment_date": "7/28/2015 16:16",
        "completion_date": "8/28/2019 11:20"
    },
    {
        "username": "username0002",
        "course_code": "coursecode_001",
        "enrollment_date": "7/28/2015 16:18",
        "completion_date": "8/7/2019 17:20",
        "score": "78"
    },
    {
        "username": "username0003",

正如您在第一个条目中看到的,"score" 键的值为 ""。我的目标是,如果值是 "",它根本不会包含该行的键。这是我为完成此任务所做的代码。

for row in csv_reader:
    for k, v in row.items():
        if v == "":
            del row[k]
        else:
            data.append(row)  

当我运行这个时,我得到 RuntimeError: dictionary changed size during iteration 的错误。

我已经查看了所有内容,并找到了一些有希望的线索,但没有任何内容能对此有实质性帮助。来自社区的任何意见都会很棒。

1 个答案:

答案 0 :(得分:0)

您收到该错误是因为您正在迭代 row.items() 并同时更改 row 中的项目。有几种方法可以解决这个问题:

  1. 在迭代之前创建 row.items() 的副本。
for row in csv_reader:
    row_items = list(row.items())
    for k, v in row_items:
        if v == "":
            del row[k]
    # Append row to data after checking all keys
    data.append(row) 
  1. 创建一个仅包含非空值的新字典,而不是从旧字典中删除键:
for row in csv_reader:
    row_filtered = {k: v for k, v in row.items() if v != ""} 
    # this line can also be written as:
    # dict(item for item in row.items() if item[1] != "")    

    # Then append the filtered row
    data.append(row_filtered)