根据属性过滤对象列表
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 作为变量名不是个好主意
我有 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 作为变量名不是个好主意