根据属性过滤对象列表

Filtering list of objects based on attribute

我有 4 个对象。

class MyObject:
    def __init__(self, id: int, result_name: str):
        self.id = id
        self.result = Result(result_name)


class Result:
    def __init__(self, name: str):
        self.name = name

object1 = MyObject(1, 'A')
object2 = MyObject(2, 'A')
object3 = MyObject(3, 'B')
object4 = MyObject(4, 'B')

它们存储在元组中:

x_ids = (object1, object2, object3, object4)

我要基于参数:

[x.result.name for x in x_ids]  
>> ("A", "A", "B", "B")

有结果列表的列表,只有两个具有“A”和“B”属性的对象

   result = (object(1or2), object(3or4))

如何使用列表理解来实现它?

您可以使用 functools 中的 reduce

让我们从创建示例数据开始:

class MyObject:
    def __init__(self, id: int, result_name: str):
        self.id = id
        self.result = Result(result_name)


class Result:
    def __init__(self, name: str):
        self.name = name

object1 = MyObject(1, 'A')
object2 = MyObject(2, 'A')
object3 = MyObject(3, 'B')
object4 = MyObject(4, 'B')

x_ids = (object1, object2, object3, object4)

现在我们执行列表理解:

from functools import reduce
result = tuple(reduce(lambda t, s: {**t, s.result.name: s}, x_ids, {}).values())

结果:

(object2, object4)

列表推导(归约)以一个空字典开始{}。每次迭代,来自 x_ids 的条目作为 s 传递给 lambda 函数,字典的当前状态作为 t 传递。通过添加带有键 s.result.name 的对象 s 来更新字典。如果该键已经存在,条目将被覆盖——这会过滤掉具有相同结果名称的对象。结果是一个字典:{'A':object2, 'B':object4}。然后将结果转换为所需的元组格式。

你可以用一组很容易地做到这一点:

class MyObject:
    def __init__(self, id_, result_name):
        self.id_ = id_
        self.result = Result(result_name)


class Result:
    def __init__(self, name):
        self.name = name

object1 = MyObject(1, 'A')
object2 = MyObject(2, 'A')
object3 = MyObject(3, 'B')
object4 = MyObject(4, 'B')

T = (object1, object2, object3, object4)

S = {o.result.name for o in T}

print(S)

输出:

{'A', 'B'}

注:

如果您需要的话,您显然可以将集合转换为列表。

使用 id 作为变量名不是个好主意