在Python字典列表上实现“select distinct ... from ...”

1 投票
3 回答
1614 浏览
提问于 2025-04-15 22:23

我遇到的问题是:我有一个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 个回答

0

可以通过哈希来实现这个任务。简单来说,就是对那些在不同查询中出现的行内容进行哈希处理,然后忽略那些哈希值相同的行。

0

distinct_list = list(set([(d['NAME'], d['CLASS']) for d in row_list]))

这里的 row_list 是你手里的一堆字典(也就是包含键值对的数据)。

这行代码的意思是:从这些字典中提取出每个字典里的 'NAME' 和 'CLASS' 这两个信息,然后把它们放在一起,形成一个元组(就是一对小括号里的值)。接着,使用 set() 函数把这些元组放到一个集合里,这样就能自动去掉重复的元组。最后,再把这个集合转换回列表,得到的就是 distinct_list,也就是不重复的 'NAME' 和 'CLASS' 的组合。

9

如果你想把它做成一个生成器:

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')):
    ...

或者类似的方式。

撰写回答