# Can One List Comprehension Be Used for both a Method and Class?

I have a simple program that determines the lateral surface area and volume of a pyramid from preset values:

``````class RightSquarePyramid():
def __init__(self, b=0, h=0):
self.b = float(b)
self.h = float(h)
pass

def slantHeight(self):
self.l = sqrt((self.h ** 2 + (self.b / 2) ** 2))
return self.l

def lateralSurfaceArea(self):
return 2 * self.b * self.l

def volume(self):
return 1/3 * self.b ** 2 * self.h

myList = [[2.5, 5.0], [4.3, 2.5], [8, 3]]

tri0, tri1, tri2 = [RightSquarePyramid(*x) for x in myList]
tri0.slantHeight()
tri1.slantHeight()
tri2.slantHeight()
print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))
``````

This happens because we only have the height and length of the base, so we need to calculate the slant height first.

I am currently using this solution:

``````tri0, tri1, tri2 = [RightSquarePyramid(*x) for x in myList]
triForce = tri0, tri1, tri2
[x.slantHeight() for x in triForce]
# tri0.slantHeight()
# tri1.slantHeight()
# tri2.slantHeight()
print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))
``````

But this essentially replaces 3 lines of code with 2.

Is there a way to use list comprehension for both `RightSquarePyramid()` and `slantHeight()`?
Maybe a common variable that I am just overlooking that could do it?

### >Solution :

You can use loops in all the cases where you’re currently enumerating all three `tri` variables. There’s no reason to destructure the list into those three variables in the first place.

The idiomatic way of writing a loop where you want to execute code for a side effect rather than doing something with its return value is to put it in a `for` loop rather than a list comprehension (the list comprehension is just going to give you a list of values that you don’t want, probably `None`s).

For the `print` cases, you can use a generator expression and the `*` operator to pass the results of the iteration as arguments to the function.

``````triForce = [RightSquarePyramid(*x) for x in myList]
for t in triForce:
t.slantHeight()

print(*(round(t.lateralSurfaceArea(), 3) for t in triForce))
print(*(round(t.volume(), 3) for t in triForce))
``````

Since you’re doing the exact same `print` routine with two different methods of the class, you could even put those in another loop:

``````for f in (
RightSquarePyramid.lateralSurfaceArea,
RightSquarePyramid.volume
):
print(*(round(f(t), 3) for t in triForce)))
``````