Home > Software engineering >  What's an elegant way to create a list of objects a list of other objects in Python?
What's an elegant way to create a list of objects a list of other objects in Python?

Time:10-06

Imagine I have two dataclasses:

class A:
   x: int
   y: int

class B:
   x:int
   y:int

And I have a list of class a:

a_list = [A(x=1, y=2), A(x=3,y=4), ...]

What would be an elegant way of creating a list of class B from this list (copying the properties over in each case)?

CodePudding user response:

Give B a class method that produces an instance of B given an instance of A:

class B
    x: int
    y: int

    @classmethod
    def from_A(cls, a):
        return cls(a.x, a.y)

Then you can write

bs = [B.from_A(a) for a in a_list]

There's a bit of an asymmetry here: B knows details about A, but A knows nothing about B. You could reverse this and let instances of A produce instances of B:

class A:
   x: int
   y: int

   def to_B(self):
       return B(self.x, self.y)

bs = [a.to_B() for a in a_list]

Or, you could decide that neither A nor B should be "privileged" to know details about the other, instead having a third "omniscient" entity that knows how to go in one direction or the other. (This is at least symmetrical.)

def b_from_a(a):
    return B(a.x, a.y)

bs = [b_from_a(a) for a in a_list]

How you decide to encapsulate the creation of a B from an A is up to you; other factors in your code may help you decide which of the three options is most reasonable.

CodePudding user response:

Assuming both are dataclasses and all of the names match up, you can pass A as keyword arguments to B's constructor using asdict.

my_b_object = B(**asdict(my_a_object))

and, of course, to apply it over a list, use a list comprehension.

b_list = [B(**asdict(a)) for a in a_list]

CodePudding user response:

Access the attributes directly and feed them into B:

b_list = [B(a.x, a.y) for a in a_list]
  • Related