如何忽略显示中的重复对象值
How to ignore duplicate object values from display
我有一个测试 class 有 3 个属性 a、b 和 c。 class 的 3 个实例已创建,并适当地设置了属性值, 它假定 'a' 属性始终是唯一的,并且当具有相同 'b' 值的两个对象将始终具有相同的 'c' 值。 如果看到此类对象,则该对象的属性 'c' 的显示将被忽略。
class test():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __repr__(self):
return 'test(%s, %s, %s)' % (self.a, self.b, self.c)
test1 = test("1", "abc", "def")
test2 = test("2", "yyy", "xxy")
test3 = test("3", "yyy", "xxy")
objList = [test1, test2, test3]
#takes out duplicate objects
new_list = [next(obj) for i, obj in
groupby(sorted(objList, key=lambda test: test.a), lambda test: test.c)]
print(new_list)
上面的代码得到如下输出。
[测试(1, abc, def), 测试(2, yyy, xxy)]
预期输出是从对象中仅省略属性 c。
[测试(1, abc, def), 测试(2, yyy, xxy), 测试(3, yyy)]
请帮忙!
已更新 REPR
要能够更改 class 正在打印的内容,您必须能够更改 repr 方法。主要是呈现的东西有点太拘束了。相反,如果 class 如下所示,那么这是可能的:
class test():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __repr__(self):
expr = []
if self.a:
expr.append(self.a)
if self.b:
expr.append(self.b)
if self.c:
expr.append(self.c)
return 'test(%s)' % (', '.join(expr))
最大的障碍是我们需要对显示的内容进行一些控制,因此我们需要更改 repr 方法。或者,您可以通过利用 str 方法并在打印前转换为字符串来生成相同的结果。
类型独立删除重复功能
因为我不知道你是确切的用例,并且想做一些与所有类型的问题相关的东西,所以我做了以下功能。它将允许您指定一个相等条件,当满足条件时做什么,以及如何对列表进行排序。
(默认检查后续值对象是否相等,如果相等则不在结果列表中包含第二个。)
def remove_dups(old_list,
condition=lambda a, b: a == b,
remove_func=lambda x, y: None,
sort_key=None):
"""
Returns a new list that has duplicates removed from `old_list`
#Arguments
old_list: list to have duplicates discarded
condition: test condition between previous and next obj to test equality.
remove_func: what to add to the list if the condition is met. If `None` is returned
then no value is added to the `new_list`
sort_key: how to sort the `old_list`.
"""
old_list = sorted(old_list, key=sort_key)
comparitor = old_list[0] #used to compare previous and current obj
new_list = [comparitor]
for i, obj in enumerate(old_list[1:]):
#if previous object and current obj are the same
if condition(comparitor, obj):
#run removal function
if remove_func:
new_value = remove_func(comparitor, obj)
else:
new_value = None
else: #then objects are different, add the new one
new_value = obj
if new_value is not None:
new_list.append(new_value)
comparitor = obj
new_value = None
return new_list
您的案例(示例)
我们可以像下面这样在您的案例中使用它
test1 = test("1", "abc", "def")
test2 = test("2", "yyy", "xxy")
test3 = test("3", "yyy", "xxy")
objList = [test1, test2, test3]
#in lambda functions `a` corresponds to previous object in list,
#`b` refers to currently observed object
new_list = remove_dups(objList,
condition=lambda a, b: a.b == b.b, #if a.b and b.b the same
remove_func=(lambda a, b: test(b.a, b.b, None)), #then set b.c = None
sort_key=lambda obj: (obj.a, obj.b, obj.c)
)
print(new_list) # [test(1, abc, def), test(2, yyy, xxy), test(3, yyy)]
编辑
如果您想在不编辑 repr 方法的情况下执行此操作,那么您可以使用 new_list
执行一些特殊的打印语句,而不是显式地尝试打印测试对象。
示例:
objList = [test1, test2, test3]
#in lambda functions `a` corresponds to previous object in list,
#`b` refers to currently observed object
new_list = remove_dups(objList,
condition=lambda a, b: a.b == b.b, #if a.b and b.b the same
remove_func=(lambda a, b: test(b.a, b.b, None)), #then set b.c = None
sort_key=lambda obj: (obj.a, obj.b, obj.c)
)
exprs = []
for test in new_list:
expr = []
if test.a:
expr.append(test.a)
if test.b:
expr.append(test.b)
if test.c:
expr.append(test.c)
exprs.append('test(%s)' % (', '.join(expr)))
print(exprs) # [test(1, abc, def), test(2, yyy, xxy), test(3, yyy)]