Compréhensions de listes avec des objets de classe

Nov 26 2020

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:

  1. appeler le sous-fichier,
  2. créer une liste de noms de données
  3. parcourez la liste pour instancier les objets; et
  4. 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

1 BillHuang Nov 26 2020 at 19:00

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)
2 DavidFrancosCuartero Nov 26 2020 at 19:26

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