python设置与对象集的交集

时间:2012-03-28 12:40:28

标签: python amazon-ec2 set intersection boto

我正在使用amazon boto,我有2个列表。列表1包含实例对象。列表2包含InstanceInfo对象。两个对象都有一个名为id的属性。我需要获取InstanceInfo列表中存在id的Instance对象列表。

l1 = [Instance:i-04072534, Instance:i-06072536, Instance:i-08072538, Instance:i-0a07253a, Instance:i-e68fa1d6, Instance:i-e88fa1d8, Instance:i-ea8fa1da, Instance:i-ec8fa1dc]

l2 = [InstanceInfo:i-ec8fa1dc, InstanceInfo:i-ea8fa1da, InstanceInfo:i-e88fa1d8, InstanceInfo:i-e68fa1d6]

通缉结果:

l3 = [Instance:i-ec8fa1dc, Instance:i-ea8fa1da, Instance:i-e88fa1d8, Instance:i-e68fa1d6]

现在我已经完成了工作:

l3= []
for a in l1  
    for b in l2:
        if a.id == b.id:
            l3.append(a)

然而,我被告知我应该使用set intersection替换它。我一直在看例子,看起来很简单。但我没有看到任何使用对象的例子。

我已经玩了一段时间,理论上我可以看到它有效,但可能有一些我可能不知道的'高级'语法。我还在学习python。

3 个答案:

答案 0 :(得分:8)

这比Marcin的回答更快(虽然相似):

ids_l1 = set(x.id for x in l1)  # All ids in list 1
intersection = [item for item in l2 if item.id in ids_l1]  # Only those elements of l2 with an id in l1

预先计算ids_l1并且不写if item.id in set(…)很重要,因为每次都会重建该集合(因为每个元素{{1}重新评估完整的测试表达式})。

Python集为您提供快速元素成员资格测试(item)。使用集合比使用列表要快得多(因为列表的元素必须逐个读取,而集合的元素是“散列”)。

答案 1 :(得分:-1)

对于小型列表,您的方法可能相对有效。

使用集合,您必须提取ID,计算ID的交集,然后将项目收集到新列表中。类似的东西:

set1 = set(x.id for x in l1)
set2 = set(x.id for x in l2)
intersection_ids = set1 & set2
intersection_list = [item for item in l2 if item.id in intersection_ids]

您可以通过扫描较短的列表或将对象存储在词典中来提高效率。

答案 2 :(得分:-3)

试试这个:

# get ids of elements in second list
l2_ids = [x.id for x in l2]
# get elements from first list that have ids in second
l3 = [x for x in l1 if x.id in l2_ids]