List comprehensions with class objects

与世无争的帅哥 提交于 2021-01-29 08:09:26

问题


I have a class named 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 the main file I:

  1. call the subfile,
  2. create a list of data names
  3. loop through the list to instantiate the objects; and
  4. load data using 'loadData' method for each object (I'm using the same 'size' and 'cost' to make this example easy.)
    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)

What I am trying to do is doing the same thing using list comprehension, to obtain

listObjects=[object1, object2, object3]

and I have tried something like

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

which doesn't work of course, but I don't know how to do it properly.

Could I please have advice on my code to obtain the desired outputs using a list comprehension??


回答1:


If you are free to append return self to the last line of StrucData.loadData() within subfile.py, it could be simplified like this:

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

Otherwise, you have to do this separately because loadData() won't return anything for a list comprehension expression.

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



回答2:


Complementing Bill Huang's response, if you're not free to change the object and you don't want to iterate twice, you could add a helper function:

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

As a side-note, if you don't really need the instance to have the name and loadData separated, you could just use a 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 would return:

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

Finally, seeing that you have names such as "data1", "data2", you might want to have that as classnames, you can do so with namedtuple as long as names are valid class identifiers:

from collections import namedtuple

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

Result:

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


来源:https://stackoverflow.com/questions/65021583/list-comprehensions-with-class-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!