将对象的两个元素添加到列表而不重复它们的最佳方法是什么?

时间:2013-03-22 13:08:23

标签: python list for-loop iteration

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

我有一系列词典:

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)

2 个答案:

答案 0 :(得分: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])

答案 1 :(得分:3)

这可以通过使用itertools.chain.from_iterable()来展平生成id的值的嵌套generator expression来轻松完成 - 我们假设所有键都是字符串,并且以{{1开头指定一个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()是展平可迭代的最有效和可读的方法。

关于id是什么,你的规范并不清楚。如果你有一组定义id的键,那么这样的东西可能更适合作为内部生成器表达式的if子句:

itertools.chain.from_iterable()