在Python字典列表上实现“select distinct ... from ...”
我遇到的问题是:我有一个Python字典的列表,这些字典的格式都是一样的,目的是用来表示数据库中一张表的行,类似于这样:
[ {'ID': 1,
'NAME': 'Joe',
'CLASS': '8th',
... },
{'ID': 1,
'NAME': 'Joe',
'CLASS': '11th',
... },
...]
我已经写了一个函数,可以从这个字典列表中获取某个字段的唯一值,这个过程很简单。这个函数的实现类似于:
select distinct NAME from ...
不过,我想要获取多个字段的唯一值,类似于:
select distinct NAME, CLASS from ...
但是我发现这并不简单。有没有什么算法或者Python自带的函数可以帮我解决这个问题呢?
在你建议我把CSV文件加载到SQLite表格里之前,得告诉你,这在我现在的环境下行不通,老实说,这也是我最初想到的办法。
3 个回答
可以通过哈希来实现这个任务。简单来说,就是对那些在不同查询中出现的行内容进行哈希处理,然后忽略那些哈希值相同的行。
distinct_list = list(set([(d['NAME'], d['CLASS']) for d in row_list]))
这里的 row_list 是你手里的一堆字典(也就是包含键值对的数据)。
这行代码的意思是:从这些字典中提取出每个字典里的 'NAME' 和 'CLASS' 这两个信息,然后把它们放在一起,形成一个元组(就是一对小括号里的值)。接着,使用 set() 函数把这些元组放到一个集合里,这样就能自动去掉重复的元组。最后,再把这个集合转换回列表,得到的就是 distinct_list,也就是不重复的 'NAME' 和 'CLASS' 的组合。
如果你想把它做成一个生成器:
def select_distinct(dictionaries, keys):
seen = set()
for d in dictionaries:
v = tuple(d[k] for k in keys)
if v in seen: continue
yield v
seen.add(v)
如果你想要结果以其他形式呈现(比如,想要一个列表而不是生成器),其实很简单,只需要稍微改一下就行(比如,使用.append
把结果加到最开始的空列表里,而不是用yield
,最后再返回这个结果列表)。
当然,你需要像这样调用它:
for values_tuple in select_distinct(thedicts, ('NAME', 'CLASS')):
...
或者类似的方式。