Python 在迭代时覆盖字典

问题描述 投票:0回答:1

我目前正在尝试将数据写入 json 文件。这是一本内部有嵌套字典的字典。我正在迭代 jsonArray,它是一个字典列表。每本词典都有特定书籍的信息。问题是我在最高级别创建了所有这些键,但嵌套信息始终是数据集中的最后一项。在所示的迭代中,我知道 info_dict 和 rating_dict 正在生成我想要的数据,但它们在 json_dict 中被数据集中的最后一项覆盖。正如您所看到的,最上层的 bookID 发生了变化,但 info 和中的数据评级总是被覆盖。

enter image description here

我不知道如何在不覆盖项目的情况下添加到字典中。 book_id 每次都是唯一的,所以我不认为“信息”或“评级”会被进一步覆盖。

这就是我现在拥有的

def retrieve_popular_books(csv_in, json_out):
    jsonArray = []
    json_dict = {}
    info_list = []
    rating_list = []
    book_id = []
    info_dict = {}
    rating_dict = {}

    with open(csv_in, newline='') as csv_file:
        csv_dict_reader = csv.DictReader(csv_file)

        for row in csv_dict_reader:
            average_rating = float(row["average_rating"])
            num_pages = int(row["num_pages"])
            ratings_count = int(row["ratings_count"])
            if average_rating > 4.50 and num_pages > 50 and ratings_count > 1000:
                jsonArray.append(row)
        
        for i in jsonArray:
            book_id = i['bookID']
            json_dict[book_id] = {}
            for k,v in i.items():
                if k != "bookID" and k!= "average_rating" and k!="ratings_count" and k!=     "text_reviews_count":
                    info_list.append({k:v})
                if k== "average_rating" or k=="ratings_count" or k== "text_reviews_count":
                    rating_list.append({k:v})
            for i in info_list:
                for k,v in i.items():
                    info_dict[k] = v
                    json_dict[book_id]["info"] = info_dict
            for i in rating_list:
                for k,v in i.items():
                    rating_dict[k] = v
                    json_dict[book_id]["ratings"] = rating_dict
   
    with open(json_out, 'w') as jsonf:
        json.dump(json_dict, jsonf, indent=4)

    retrieve_popular_books('books_data/books_v2.csv', 'books_data/books_v2_copy.json')`

我得到了什么。最上面的键发生了变化,但信息是我们从中提取的数据集中的最终条目。

{
    "863f3fd8-b4f5-43b8-8ec1-eb870faa334e": {
        "info": {
            "title": "Fullmetal Alchemist  Vol. 6 (Fullmetal Alchemist  #6)",
            "authors": "Hiromu Arakawa/Akira Watanabe",
            "isbn": "1421503190",
            "isbn13": "9781421503196",
            "language_code": "eng",
            "num_pages": "200",
            "publication_date": "3/21/2006",
            "publisher": "VIZ Media LLC"
        },
        "ratings": {
            "average_rating": "4.58",
            "ratings_count": "10052",
            "text_reviews_count": "201"
        }
    },
    "b343cec8-66dc-470a-8efe-47858e37aab5": {
        "info": {
            "title": "Fullmetal Alchemist  Vol. 6 (Fullmetal Alchemist  #6)",
            "authors": "Hiromu Arakawa/Akira Watanabe",
            "isbn": "1421503190",
            "isbn13": "9781421503196",
            "language_code": "eng",
            "num_pages": "200",
            "publication_date": "3/21/2006",
            "publisher": "VIZ Media LLC"
        },
        "ratings": {
            "average_rating": "4.58",
            "ratings_count": "10052",
            "text_reviews_count": "201"
        }
python dictionary iteration
1个回答
0
投票

字典和列表仅存储对其他地方包含的对象的引用。您只为

info_list
rating_list
之一创建一个列表对象,并不断地一遍又一遍地修改它。相反,您需要创建一个 new
info_list
rating_list
。一般来说,使用字典访问并在变量中保留对所需结构的引用是有益的,这样你就可以像这样以更Pythonic的方式做到这一点:

for i in jsonArray:
    # pop the bookID so that we don't need to ignore it later!
    book_id = i.pop("bookID")

    info = []
    ratings = []
    book = {"info": info, "ratings": ratings}
    json_dict[book_id] = book

    if k in {"average_rating", "ratings_count", "text_reviews_count"}:
        ratings.append({k: v})
    else:
        info.append({k: v})
© www.soinside.com 2019 - 2024. All rights reserved.