Listy składane z obiektami klas

Nov 26 2020

Mam klasę o nazwie StrucData w subfile.py

class StrucData:  
def __init__(self, name):
    self.name=name

def loadData(self, size=1, cost=1):
    self.size=size  
    self.cost=cost

W głównym pliku I:

  1. wywołaj podplik,
  2. utwórz listę nazw danych
  3. przejrzyj listę, aby utworzyć instancję obiektów; i
  4. załaduj dane za pomocą metody „loadData” dla każdego obiektu (używam tego samego „rozmiaru” i „kosztu”, aby ułatwić ten przykład).
    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)

To, co próbuję zrobić, to zrobić to samo, używając rozumienia list, aby uzyskać

listObjects=[object1, object2, object3]

i próbowałem czegoś takiego

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

co oczywiście nie działa, ale nie wiem, jak to zrobić poprawnie.

Czy mógłbym prosić o radę na temat mojego kodu, aby uzyskać żądane wyniki za pomocą rozumienia listy?

Odpowiedzi

1 BillHuang Nov 26 2020 at 19:00

Jeśli możesz dołączyć return selfdo ostatniego wiersza w StrucData.loadData()ciągu subfile.py, można to uprościć w następujący sposób:

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

W przeciwnym razie musisz to zrobić osobno, ponieważ loadData()nie zwróci niczego dla wyrażenia listy.

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

Uzupełniając odpowiedź Billa Huanga, jeśli nie możesz zmieniać obiektu i nie chcesz powtarzać iteracji, możesz dodać funkcję pomocniczą:

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

Na marginesie, jeśli tak naprawdę nie potrzebujesz, aby instancja miała oddzieloną nazwę i loadData, możesz po prostu użyć namedtuple:

from collections import namedtuple

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

Który zwróciłby:

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

Wreszcie, widząc, że masz takie nazwy, jak „dane1”, „dane2”, możesz chcieć je mieć jako nazwy klas, możesz to zrobić za pomocą namedtuple, o ile nazwy są prawidłowymi identyfikatorami klas:

from collections import namedtuple

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

Wynik:

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