需要从字典列表中删除(并部分合并)几乎重复的项



我有一个这种形式的字典列表:(示例)[{name: aa, year: 2022}, {name: aa, year: 2021}, {name: bb, year: 2016}, {name: cc, year: 2015}]。我需要的是删除名字相同的项目,但是制作一个年份加在一起的列表(每年都可以在一个列表中,对于我的目的,这并不重要)。所以字典的示例列表看起来像这样:[{name: aa, year: [2022, 2021}, {name: bb, year: [2016]}, {name: cc, year:[2015]}]。我当前的代码是这样的:

def read_csv_file(self, path):
book_list = []
with open(path) as f:
read_dict = csv.DictReader(f)
for i in read_dict:
book_list.append(i)

bestsellers = []
for i in list_of_books:
seen_books = []
years_list = []
if i["Name"] not in seen_books:
years_list.append(i["Year"])
seen_books.append(i)
else:
years_list.append(i["Year"])
if i['Genre'] == 'Non Fiction':
bestsellers.append(FictionBook(i["Name"], i["Author"], float(i["User Rating"]), int(i["Reviews"]), float(i["Price"]), years_list, i["Genre"]))
else:
bestsellers.append(NonFictionBook(i["Name"], i["Author"], float(i["User Rating"]), int(i["Reviews"]), float(i["Price"]), years_list, i["Genre"]))
for i in bestseller:
print(i.title)

最终,我的代码需要从csv文件中提取数据,然后根据类型创建类Fictionbook或Nonfictionbook的实例。我想我已经有了CSV文件并完成了书籍,我只需要过滤几乎重复的字典并将它们合并到年份列表中,如果这有意义的话。如果有什么不清楚的地方,请告诉我,以便我进一步解释。

如果键还没有被看到,使用dict.setdefault()创建一个列表:

lod=[{'name': 'aa', 'year': 2022}, {'name': 'aa', 'year': 2021}, {'name': 'bb', 'year': 2016}, {'name': 'cc', 'year': 2015}]
result={}
for d in lod:
result.setdefault(d['name'], []).append(d['year'])
>>> result
{'aa': [2022, 2021], 'bb': [2016], 'cc': [2015]}

然后把列表放回一起:

>>> [{'name': n, 'year': v} for n,v in result.items()]
[{'name': 'aa', 'year': [2022, 2021]}, {'name': 'bb', 'year': [2016]}, {'name': 'cc', 'year': [2015]}]
从评论:

回答得好,谢谢。如果每个字典有超过2个键值对,我该如何在系统中实现这一点呢?例如{name: aa, singer: bb, album: gg, year: 2022}

我会用不同的方式去做你所描述的。看起来你正在创建一个图书、专辑和作者的数据库。使用一个类来描述您想要编目的数据片段。

考虑下面这个关于艺术品、书籍等的简单条目:

class Entry:
def __init__(self, n, name=None, author=None, singer=None, title=None, year=None):
self.num=n
self.title=title
self.singer=singer
self.name=name
self.year=year
self.author=author
# etc

def __repr__(self):   # allows each item to be printed
return repr(({self.num}, {self.year}, {self.author}))

现在创建一些虚拟条目:

import random
entries=[Entry(i, 
author=random.choice(['Bob', 'Carol', 'Ted', 'Alice', 'Lisa']),
year=random.randint(1700, 2022)
) 
for i in range(3_000_000)]

创建3,000,000个条目(略多于美国国会图书馆图书目录的1%)大约需要5秒。

你可以这样查询:

# book for 1799 with an author with 'a' in the name?
[e for e in entries if e.year==1799 and 'a' in e.author.lower() ]

这个查询在我的电脑上大约花了1.4秒。

使用更好的数据结构会比使用对象列表(这些对象是字典或这里显示的对象)快得多。

候选将是树的一种形式,但这完全取决于您希望从该数据中查询什么。杜威十进制是树的一种特殊形式。

这行得通:

dict_list = [{'name': 'aa', 'year': 2022}, {'name': 'aa', 'year': 2021}, {'name': 'bb', 'year': 2016}, {'name': 'cc', 'year': 2015}]
new_dict_list = []
names_seen = set()
for name in [d['name'] for d in dict_list]:
if not name in names_seen:
new_dict_list.append({'name':name, 'year':[d['year'] for d in dict_list if d['name']==name]})
names_seen.add(name)
new_dict_list
# Out[68]: 
# [{'name': 'aa', 'year': [2022, 2021]},
#  {'name': 'bb', 'year': [2016]},
#  {'name': 'cc', 'year': [2015]}]

相关内容

  • 没有找到相关文章

最新更新