对于我正在处理的应用程序,我正在搜索文件目录,并希望找到匹配的文件对来执行进一步的分析。
在这种情况下,一对被定义为在某些属性子集上匹配,但在某些其他属性上有所不同。
作为错误处理/警告的一部分,我想识别找到的无法比较的任何文件,"即期望的"合作伙伴"在这对中找不到。
我有一类对象来存储结构化属性信息,当我读取目录中的文件时,我将每个找到的文件存储为这些对象列表中的元素。
这是一个愚蠢的简单例子
class glove(object):
def __init__(self, size, color, is_right):
self.size = size
self.color = color
self.is_right = is_right
def __repr__(self):
if self.is_right:
hand = "right"
else:
hand = "left"
s = "{} {} {}".format(self.size, self.color, hand)
return(s)
gloves = [glove('med', 'black', False),
glove('med', 'black', True),
glove('lg', 'black', False),
glove('lg', 'black', True),
glove('med', 'brown', False),
glove('med', 'brown', True),
glove('lg', 'blue', False),
glove('med', 'tan', False)]
left_gloves = [x for x in gloves if not x.is_right]
right_gloves = [x for x in gloves if x.is_right]
我们假设列表中没有重复的元素,让我们定义一个"对"作为两个glove
个匹配glove.size
和glove.color
但glove.is_right
值不同的对象(即一个是右,一个是左)。
现在我想识别不完整的对(可能是leftovers
的列表,以便我可以错误或警告,例如"没有找到左手蓝色手套"&# 34;没有找到左手棕褐色手套。"
我看过answers教授如何识别物品"失踪"从列表对,但我的应用程序有一些复杂性,我无法弄清楚如何解决:链接对象的属性,以及链接对象的多个属性。
我认为for循环和列表理解可以实现一些东西,但我无法弄清楚如何将它们连接在一起。
答案 0 :(得分:2)
如果你可以为你的类实现相等/哈希,这很容易:
[lg blue left, med tan left]
输出:
class glove(object):
def __init__(self, size, color, is_right):
self.size = size
self.color = color
self.is_right = is_right
def __repr__(self):
if self.is_right:
hand = "right"
else:
hand = "left"
s = "{} {} {}".format(self.size, self.color, hand)
return(s)
gloves = [glove('med', 'black', False),
glove('med', 'black', True),
glove('lg', 'black', False),
glove('lg', 'black', True),
glove('med', 'brown', False),
glove('med', 'brown', True),
glove('lg', 'blue', False),
glove('med', 'tan', False)]
# With plain dict
glove_search = {}
for g in gloves:
glove_search.setdefault(g.size, {}).setdefault(g.color, {})[g.is_right] = True
unpaired = [g for g in gloves
if not glove_search.get(g.size, {}).get(g.color, {}).get(not g.is_right, False)]
# Or, more idiomatically, with defaultdict
from collections import defaultdict
glove_search = defaultdict(lambda: defaultdict(lambda: defaultdict(bool)))
for g in gloves:
glove_search[g.size][g.color][g.is_right] = True
unpaired = [g for g in gloves if not glove_search[g.size][g.color][not g.is_right]]
print(unpaired)
你也可以考虑使用namedtuple
,它实际上是为你做的。
这是一个不需要实现equals和hash,也不需要创建新对象的替代方法:
[lg blue left, med tan left]
输出:
foo_AUDIT
答案 1 :(得分:2)
不允许重复,问题相对简单。 连接您的标识符:
self.ID = self.size + " " + self.color
仅在ID上构建左/右子集。
left = {g.ID for g in gloves if not g.is_right)
right = {g.ID for g in gloves if g.is_right)
unmatched_left = left - right
unmatched_right = right - left
现在,只需反转关键过程即可获得手套对象:
unmatched = [g for g in glove_set \
if g.ID in unmatched_left + unmatched_right]