クラスオブジェクトを含むリスト内包表記

Nov 26 2020

subfile.pyにStrucDataという名前のクラスがあります

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

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

メインファイルで私は:

  1. サブファイルを呼び出し、
  2. データ名のリストを作成する
  3. リストをループしてオブジェクトをインスタンス化します。そして
  4. オブジェクトごとに「loadData」メソッドを使用してデータをロードします(この例を簡単にするために、同じ「サイズ」と「コスト」を使用しています)。
    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)

私がやろうとしているのは、リスト内包表記を使って同じことをして、

listObjects=[object1, object2, object3]

そして私は次のようなことを試みました

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

もちろん動作しませんが、正しく行う方法がわかりません。

リスト内包表記を使用して目的の出力を取得するためのコードに関するアドバイスをいただけますか?

回答

1 BillHuang Nov 26 2020 at 19:00

return selfの最後の行に自由に追加できる場合は、次のように簡略化できます。StrucData.loadData()subfile.py

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

それ以外の場合loadData()は、リスト内包表記式に対して何も返さないため、これを個別に行う必要があります。

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

Bill Huangの応答を補完するものとして、オブジェクトを自由に変更できず、2回繰り返したくない場合は、ヘルパー関数を追加できます。

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

補足として、名前とloadDataを分離するインスタンスを実際に必要としない場合は、namedtupleを使用できます。

from collections import namedtuple

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

Wichは戻ります:

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

最後に、「data1」、「data2」などの名前がある場合は、それをクラス名として使用することをお勧めします。名前が有効なクラス識別子である限り、namedtupleを使用してこれを行うことができます。

from collections import namedtuple

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

結果:

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