这是垂直切片字典列表以获取唯一值的最有效方法吗?

Jam*_*mie 2 python python-2.7

我有一个字典列表,我正在寻找其中一个键的唯一值列表.

这就是我想出来的,但不禁想知道它的效率,时间和/或记忆是否明智:

list(set([d['key'] for d in my_list]))
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

aba*_*ert 6

这个:

list(set([d['key'] for d in my_list]))
Run Code Online (Sandbox Code Playgroud)

...构造所有值的列表,然后构造一组唯一的值,然后构造一个列表.

假设您有10000件商品,其中1000件是独一无二的.您已将最终存储量从10000个项目减少到1000个,这很好 - 但您已将峰值存储量从10000增加到11000(因为显然必须有整个列表和几乎整个集合同时存在于内存中的时间).

有两种非常简单的方法可以避免这种情况.

首先(只要你有Python 2.4或更高版本)使用生成器表达式而不是列表理解.在大多数情况下,包括这个,只需要删除方括号或将它们变成括号:

list(set(d['key'] for d in my_list))
Run Code Online (Sandbox Code Playgroud)

或者,更简单地(使用Python 2.7或更高版本),只需使用set comprehension而不是list comprehension直接构造集合:

list({d['key'] for d in my_list})
Run Code Online (Sandbox Code Playgroud)

如果您遇到Python 2.3或更早版本,则必须编写显式循环.对于2.2或更早版本,没有集合,所以你必须使用dict映射每个键None或类似的伪造它.


超越太空,时间怎么样?好吧,显然你必须遍历10000个字典的整个列表,并dict.get为每个字典做一个O(1).

原始版本list.append为每个步骤执行一个(实际上稍微快一点的内部等效),然后set转换是遍历相同大小的列表,set.add每个步骤都有一个,然后list转换是一个较小集的遍历与list.append用于每一个.因此,它是O(N),它在算法上显然是最优的,并且只是通过一个小的乘数而不仅仅是迭代列表并且什么都不做而更糟.

设置版本跳过list.appends,只迭代一次而不是两次.所以,它也是O(N),但乘数更小.内存管理的节省(如果N足够重要)也可能有所帮助.

  • @abarnert它仍然指出了随便的SO访客. (3认同)
  • 注意:设置理解在3.x和2.7中 (2认同)