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)]