【问题标题】:querying/retrieving objects stored in a list (python 3.3)查询/检索存储在列表中的对象(python 3.3)
【发布时间】:2014-01-31 10:08:32
【问题描述】:

在我的 Python 作业简介中,我创建了类的实例,存储在列表中。我可以按它们在列表中的位置打印或删除它们,但实际上,我需要能够查询单个属性,例如只过滤可用的属性、更改它们的可用性或显示每个对象的成本。我会附上一些代码:

class Vehicle():
    def __init__(self,plateno,kml,dailycost,weeklycost,weekendcost):            #attributes common to all vehicles
        self.plateno=plateno
        self.kml=kml
        self.dailycost=dailycost
        self.weeklycost=weeklycost
        self.weekendcost=weekendcost
        self.avail=True

#   methods

    def __str__(self):b
        return "Vehicle Plate Number: {0}, km/l: {1}, daily: {2},weekly: {3}, weekend: {4}".format(self.plateno, self.kml, self.dailycost, self.weeklycost, self.weekendcost)

    def __del__(self):
        return "Vehicle deleted: {0}".format(self.plateno)



class Cvn(Vehicle):
    def __init__(self,plateno,kml,bedno,dailycost,weeklycost,weekendcost):
        Vehicle.__init__(self,plateno,kml,dailycost, weeklycost, weekendcost)
        self.bedno=bedno

    def __str__(self):
        return "Caravan: Plate Number: {0}, km/l: {1}, number of beds: {2}, daily: {3},weekly: {4}, weekend: {5}, Available? {6}".format(self.plateno, self.kml, self.bedno, self.dailycost, self.weeklycost, self.weekendcost, self.avail)


#   I N S T A N C E S

  #   C A R A V A N S   Class:Cvn
  #   (self,plateno,kml,bedno,dailycost,weeklycost,weekendcost)

#------------------
#caravanheaders=["Km/l","Number of beds","Plate number","Daily cost","Weekly cost","Weekend cost"]
cvn1=[12,4,"11-D-144",50,350,200]
cvn2=[10,6,"10-D-965",50,365,285]         #values as per Caravan table
cvn3=[11,4,"12-C-143",50,350,200]
cvn4=[15,2,"131-G-111",50,250,185]

cvnslist=[cvn1,cvn2,cvn3,cvn4]    #this list contains 4 variables, each representing a list, as above
cvns=[]                           #this is going to be the list of lists

for i in cvnslist:          #this loop creates a list of lists 'cvns'
     cvns.append(i)
print("")
print(cvns)             #the list of lists

cvninstances=[]
for i in range(len(cvns)):
    cvninstances.append(Cvn(cvns[i][2],cvns[i][0],cvns[i][1],cvns[i][3],cvns[i][4],cvns[i][5]))
    vehlist.append(Cvn(cvns[i][2],cvns[i][0],cvns[i][1],cvns[i][3],cvns[i][4],cvns[i][5]))

#    print(cvninstances)  #this shows just that there are objects, but not their attibutes
#for i in cvninstances:
#    print(i)
print("")

for i in vehlist:
    print("On Vehicles List: ",i)
print("")
print("Initial fleet displayed.")
print("")

#---------------------------------------------------------------------------------

对于我来说不幸的是,这里对类似问题的大多数答案都处于更高级的水平!

【问题讨论】:

  • 你知道如何获取实例的属性吗?
  • 我知道我创建的一个对象,例如Student1=Student("Mary"),我可以通过调用Student1.name(Class being Student(self,name))得到Mary这个名字...

标签: python list class object instance


【解决方案1】:

确实,我认为@sweeneyrod 明白了这一点:在我看来,您的问题也是访问实例的属性,可以这样做:

instance.attribute

如果是这种情况,请再次阅读:http://docs.python.org/2/tutorial/classes.html#instance-objects

另外,这段代码可以用更优雅的方式重写:

cvninstances.append(Cvn(cvns[i][2],cvns[i][0],cvns[i][1],cvns[i][3],cvns[i][4],cvns[i][5]))

我会首先重新排序您的 cvn_i 列表,以便参数与 Cvn __init__ 方法的顺序相同,然后将其写为:

cvninstances.append(Cvn(*cvns[i]))

* 的含义如下:“获取 cvns[i] 中的所有项,并将它们用作参数来实例化一个 Cvn”

(也许这太“高级”了——用你自己的话来说——但我认为这绝对是你必须知道的模式;))


[添加]

Cf cmets,过滤,使用列表推导:

[veh for veh in vehlist if veh.avail==True]

可以用更短的方式写成这样(因为 veh.avail 打算包含一个布尔值):

[veh for veh in vehlist if veh.avail]

如果您习惯于数据库查询,这 - 从概念上讲 - 非常相似 :)

[/已添加]

【讨论】:

  • 感谢您,我之前使用过 instance.attribute,但在这种情况下,除了通过它在列表中的位置之外,我不确定如何访问该实例。如果我想列出所有的avail=True,我是否必须通过一个循环检查每一个并将它们添加到一个新列表中,还是有更快的方法?我更习惯于非常基本的数据库查询而不是实际编程,所以这对我来说是一个陡峭的学习曲线!
  • 事实上,在编写类似 [veh for veh in vehlist if veh.avail==True] 之类的内容时,您会同时做这两件事。您正在过滤并隐式创建一个将存储结果的新列表。对于信息,我发现理解列表更自然,因为它几乎与您在使用集合时可以在数学中编写的内容相同(并且毕竟“理解”的名称与集合论公理相同:p)
  • [veh for veh in vehlist if veh.avail==True] 可以简化为 [veh for veh in vehlist if veh.avail]。但我更喜欢明确地编写 ==True 子句,以便您更清楚;)
  • 我会试试那个,谢谢。自然、明确和清晰绝对是我的首要任务,谢谢!
  • @backtoschool :如果有帮助,请将问题标记为已回答 :)
【解决方案2】:

你会发现filter在这里很有用:

filter(function, iterable):从函数返回 true 的可迭代元素中构造一个列表。 iterable 可以是序列、支持迭代的容器或迭代器。如果 iterable 是字符串或元组,则结果也具有该类型;否则它总是一个列表。如果function为None,则假定恒等函数,即iterable中所有为假的元素都被移除。

您可以使用lambda 创建任意过滤函数:

matches = filter(lambda x: x.attr == val, obj_list)

这将为您提供属性attr 的值为val 的所有对象实例的列表。如果您想要多个可能的值,例如可能的vals列表:

lambda x: x.attr in vals

您也可以使用list comprehensions 来执行此操作,这在 Python 中很常见:

matches = [i for i in obj_list if i.attr == val]

【讨论】:

  • 当然这是一个好点,但在我看来,backtoschool 正在学习 Python,因此使用理解列表将是一种更“自然”的方式:类似于:[it​​em for item in lst if item.attr=val]
猜你喜欢
  • 2011-12-17
  • 1970-01-01
  • 2012-10-11
  • 2022-01-21
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 2019-10-28
  • 2013-10-03
相关资源
最近更新 更多