Compréhensions de listes avec des objets de classe
J'ai une classe nommée StrucData dans subfile.py
class StrucData:
def __init__(self, name):
self.name=name
def loadData(self, size=1, cost=1):
self.size=size
self.cost=cost
Dans le fichier principal I:
- appeler le sous-fichier,
- créer une liste de noms de données
- parcourez la liste pour instancier les objets; et
- chargez des données en utilisant la méthode 'loadData' pour chaque objet (j'utilise la même 'taille' et 'coût' pour rendre cet exemple facile.)
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)
Ce que j'essaie de faire, c'est de faire la même chose en utilisant la compréhension de liste, pour obtenir
listObjects=[object1, object2, object3]
et j'ai essayé quelque chose comme
listObjects=[[StrucData(listIndex[i]) for k in range(3)] listObjects[i].loadData(size=3, cost=4) for i in range(3)]]
ce qui ne fonctionne pas bien sûr, mais je ne sais pas comment le faire correctement.
Pourrais-je s'il vous plaît avoir des conseils sur mon code pour obtenir les résultats souhaités en utilisant une compréhension de liste ??
Réponses
Si vous êtes libre d'ajouter return self
à la dernière ligne de StrucData.loadData()
inside subfile.py
, cela pourrait être simplifié comme ceci:
# in the main file
listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]
Sinon, vous devez le faire séparément car vous loadData()
ne retournerez rien pour une expression de compréhension de liste.
listObjects = [StrucData(idx) for idx in listIndex]
for i in range(3):
listObjects[i].loadData(size=3, cost=4)
En complément de la réponse de Bill Huang, si vous n'êtes pas libre de modifier l'objet et que vous ne voulez pas répéter deux fois, vous pouvez ajouter une fonction d'assistance:
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)]
En remarque, si vous n'avez pas vraiment besoin que l'instance ait le nom et loadData séparés, vous pouvez simplement utiliser un namedtuple:
from collections import namedtuple
StructData = namedtuple('StructData', ['name', 'size', 'cost'])
print([StructData(name=x, size=3, cost=4) for x in range(3)])
Ce qui reviendrait:
[StructData(name=0, size=3, cost=4),
StructData(name=1, size=3, cost=4),
StructData(name=2, size=3, cost=4)]
Enfin, étant donné que vous avez des noms tels que "data1", "data2", vous voudrez peut-être les avoir comme noms de classe, vous pouvez le faire avec namedtuple tant que les noms sont des identificateurs de classe valides:
from collections import namedtuple
list_index = ['data1', 'data2', 'data3']
print([namedtuple(name, ['size', 'cost'])(3, 4) for name in list_index])
Résultat:
[data1(size=3, cost=4), data2(size=3, cost=4), data3(size=3, cost=4)]