问题
I have a class named StrucData in subfile.py
class StrucData:
def __init__(self, name):
self.name=name
def loadData(self, size=1, cost=1):
self.size=size
self.cost=cost
In the main file I:
- call the subfile,
- create a list of data names
- loop through the list to instantiate the objects; and
- load data using 'loadData' method for each object (I'm using the same 'size' and 'cost' to make this example easy.)
from subfile import StrucData
listIndex=['data1','data2','data3']
# Create a list of objects
listObjects=[]
# Iterate through the list of objects
for i in range(3):
data=StrucData(listIndex[i])
data.loadData(size=3, cost=4)
listObjects.append(data)
What I am trying to do is doing the same thing using list comprehension, to obtain
listObjects=[object1, object2, object3]
and I have tried something like
listObjects=[[StrucData(listIndex[i]) for k in range(3)] listObjects[i].loadData(size=3, cost=4) for i in range(3)]]
which doesn't work of course, but I don't know how to do it properly.
Could I please have advice on my code to obtain the desired outputs using a list comprehension??
回答1:
If you are free to append return self
to the last line of StrucData.loadData()
within subfile.py
, it could be simplified like this:
# in the main file
listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]
Otherwise, you have to do this separately because loadData()
won't return anything for a list comprehension expression.
listObjects = [StrucData(idx) for idx in listIndex]
for i in range(3):
listObjects[i].loadData(size=3, cost=4)
回答2:
Complementing Bill Huang's response, if you're not free to change the object and you don't want to iterate twice, you could add a helper function:
def load_data(idx, size, cost):
result = StructData(idx)
result.loadData(size, cost)
return result
[load_data(x, size=3, cost=4) for x in range(3)]
As a side-note, if you don't really need the instance to have the name and loadData separated, you could just use a namedtuple:
from collections import namedtuple
StructData = namedtuple('StructData', ['name', 'size', 'cost'])
print([StructData(name=x, size=3, cost=4) for x in range(3)])
Wich would return:
[StructData(name=0, size=3, cost=4),
StructData(name=1, size=3, cost=4),
StructData(name=2, size=3, cost=4)]
Finally, seeing that you have names such as "data1", "data2", you might want to have that as classnames, you can do so with namedtuple as long as names are valid class identifiers:
from collections import namedtuple
list_index = ['data1', 'data2', 'data3']
print([namedtuple(name, ['size', 'cost'])(3, 4) for name in list_index])
Result:
[data1(size=3, cost=4), data2(size=3, cost=4), data3(size=3, cost=4)]
来源:https://stackoverflow.com/questions/65021583/list-comprehensions-with-class-objects