0

性能、优雅和可读性“最佳方式”的要求

我有字典数组:

items = [
    {'id1' : 1, 'id2' : 2, 'other' : 'xxx'},
    {'id1' : 1, 'id2' : 3, 'other' : 'yyy'},
    {'id1' : 2, 'id2' : 4, 'other' : 'zzz'}
]

结果应该是:ids = [1,2,3,4](id1 和 id2 的列表)

编辑: 像这样的东西:

ids = []
for item in items:
   if item.id1 not in ids:
       ids.append(item.id1)
   if item.id2 not in ids:
       ids.append(item.id2)
4

2 回答 2

4
>>> set(x for y in items for x in y.values())
set([1, 2, 3, 4])

更新更新的问题

>>> set(v for y in items for (k,v) in y.items() if k.startswith('id'))
set([1, 2, 3, 4])
于 2013-03-22T13:11:45.950 回答
3

这可以通过使用itertools.chain.from_iterable()扁平化生成 id 值的嵌套生成器表达式来轻松完成- 我们假设所有键都将是字符串,并且以指定的开头"id"指定一个 id。然后我们制作一组这些值来删除重复项:

from itertools import chain

set(chain.from_iterable((value for name, value in item.items() 
                         if name.startswith("id"))
                        for item in items))

如果你真的想要一个列表,那么你可以从集合中创建一个,但在大多数情况下,集合应该是原样的。请注意,该集合没有顺序,因此如果您想要一个顺序,您将需要使用sorted(),例如。

itertools.chain.from_iterable()是扁平化迭代的最有效和可读的方法。

当涉及到什么是 id 时,您的规范不清楚。如果您有一组定义 id 的键,那么像这样的内容可能更适合作为内部生成器表达式的 if 子句:

if name in {"id1", "id2"}
于 2013-03-22T13:11:49.617 回答