I have 4 objects.
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')
They're stored in a tuple:
x_ids = (object1, object2, object3, object4)
I want bases on parameters:
[x.result.name for x in x_ids]
>> ("A", "A", "B", "B")
Have list of resulting list, just two objects with "A", and "B" attribute
result = (object(1or2), object(3or4))
How can I achieve it with list comprehensions?
CodePudding user response:
You can do this very easily with a set:
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)
Output:
{'A', 'B'}
Note:
You could obviously convert the set to a list if that's what you need.
Use of id not a great idea as a variable name
CodePudding user response:
You can that using reduce
from functools
.
Let's start by creating the sample data:
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)
Now we perform the list comprehension:
from functools import reduce
result = tuple(reduce(lambda t, s: {**t, s.result.name: s}, x_ids, {}).values())
Result:
(object2, object4)
The list comprehension (reduce) starts with an empty dict {}
. Each iteration, an entry from x_ids
is passed to the lambda function as s
and the current state of the dict is passed as t
. The dict gets updated by adding the object s
with key s.result.name
. If that key already exists, the entry will be overwritten - this filters out objects with the same result name. The result is a dict: {'A':object2, 'B':object4}
. The result is then converted into the required tuple format.