我想在列表中找到任何具有相同属性的元素。例如,
class X:
def __init__(self, param):
self.param = param
my_list = [X(1), X(2), X(3), X(2), X(3), X(3)]
因此,如果在x.param
上进行比较,我会寻找my_list[1], my_list[3]
或my_list[2], my_list[4]
或my_list[2], my_list[5]
或my_list[4], my_list[5]
。但是,不能保证该列表必需要具有相同属性的任何元素,例如
my_list = [X(1), X(2), X(3)]
可能也是此功能的有效参数。
执行此操作的明显方法似乎是:
def find_dupe(my_list, my_lambda):
attrs = dict()
for item in my_list:
if my_lambda(item) in attrs:
return [attrs[my_lambda(item)], item]
attrs[my_lambda(item)] = item
return []
但是似乎有点不雅,我想知道是否有更好的方法可以做到这一点。
答案 0 :(得分:6)
collections.defaultdict
提供了一种O(n)解决方案,用于按属性对对象进行分组:
from collections import defaultdict
class X:
def __init__(self, param):
self.param = param
my_list = [X(1), X(2), X(3), X(2), X(3), X(3)]
d = defaultdict(list)
for i in my_list:
d[i.param].append(i)
结果表明一个对象为param == 1
,两个对象为param == 2
,三个对象为param == 3
:
print(d)
defaultdict(list,
{1: [<__main__.X at 0x855eb70>],
2: [<__main__.X at 0x855e588>, <__main__.X at 0x856ae48>],
3: [<__main__.X at 0x856af60>, <__main__.X at 0x856ad68>, <__main__.X at 0x856acf8>]})
要提取具有相同属性的对象的对,您只需要过滤字典中长度大于1的值的项即可。然后使用itertools.combinations
提取以下项的所有组合:这些键。