Listenverständnisse mit Klassenobjekten auflisten

Nov 26 2020

Ich habe eine Klasse namens 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 der Hauptdatei I:

  1. Rufen Sie die Subdatei auf,
  2. Erstellen Sie eine Liste mit Datennamen
  3. Durchlaufen Sie die Liste, um die Objekte zu instanziieren. und
  4. Laden Sie Daten mit der Methode 'loadData' für jedes Objekt (ich verwende dieselbe 'Größe' und 'Kosten', um dieses Beispiel zu vereinfachen.)
    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)

Was ich versuche, ist das Gleiche mit Listenverständnis zu tun, um zu erhalten

listObjects=[object1, object2, object3]

und ich habe so etwas versucht

listObjects=[[StrucData(listIndex[i]) for k in range(3)] listObjects[i].loadData(size=3, cost=4) for i in range(3)]]

Das funktioniert natürlich nicht, aber ich weiß nicht, wie ich es richtig machen soll.

Könnte ich bitte Ratschläge zu meinem Code haben, um die gewünschten Ausgaben unter Verwendung eines Listenverständnisses zu erhalten?

Antworten

1 BillHuang Nov 26 2020 at 19:00

Wenn Sie frei sind, return selfan die letzte Zeile von StrucData.loadData()innen anzuhängen subfile.py, könnte dies folgendermaßen vereinfacht werden:

# in the main file
listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]

Andernfalls müssen Sie dies separat ausführen, da loadData()für einen Listenverständnisausdruck nichts zurückgegeben wird.

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

Als Ergänzung zu Bill Huangs Antwort können Sie eine Hilfsfunktion hinzufügen, wenn Sie das Objekt nicht ändern können und nicht zweimal iterieren möchten:

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

Als Randnotiz: Wenn Sie die Instanz nicht wirklich benötigen, um den Namen und loadData zu trennen, können Sie einfach ein namedtuple verwenden:

from collections import namedtuple

StructData = namedtuple('StructData', ['name', 'size', 'cost'])
print([StructData(name=x, size=3, cost=4) for x in range(3)])

Was würde zurückkehren:

[StructData(name=0, size=3, cost=4), 
 StructData(name=1, size=3, cost=4), 
 StructData(name=2, size=3, cost=4)]

Wenn Sie schließlich Namen wie "data1", "data2" haben, möchten Sie diese möglicherweise als Klassennamen verwenden. Dies können Sie mit namedtuple tun, solange Namen gültige Klassenbezeichner sind:

from collections import namedtuple

list_index = ['data1', 'data2', 'data3']
print([namedtuple(name, ['size', 'cost'])(3, 4) for name in list_index])

Ergebnis:

[data1(size=3, cost=4), data2(size=3, cost=4), data3(size=3, cost=4)]