【问题标题】:Assignment: Python 3.3: add keys and values from dictionary to class作业:Python 3.3:将键和值从字典添加到类
【发布时间】:2013-04-29 20:43:45
【问题描述】:

如何从字典中获取键/值对,并将其用作类实例中的属性?我确定它应该通过一个 for 循环,但我不确定要使用什么语法。这是我的代码:

from random import randint
import time
drivers={}

class car:
    def __init__(self, Driver, Sponsor, Odometer=0,Speed=randint(1,121)):
        self.Driver = Driver
        self.Sponsor = Sponsor
        self.Odometer = Odometer
        self.Speed = Speed
    def update():
        Odometer=Odometer+Speed*0.17
        Speed = randint(1,121)
drivers['David']='Burger King'
drivers['Travis']='Dr Pepper'
drivers['Landon']='Precon Marine'
drivers['Jamie']='Cessna'
drivers['Juan']='Target'
drivers['Ken']='Federated Auto Parts'
drivers['Timmy']='OXYwater'
drivers['Josh']='MDS Transport'
drivers['Kurt']='Furniture Row'
drivers['Casey']='Geico'
drivers['Kasey']='Farmers Insurance'
drivers['Jeff']='Axalta'
drivers['Jimmie']='Lowes'
drivers['Dale']='National Guard'
drivers['Mike']='Plinker Tactical'
drivers['Denny']='FedEx'
drivers['Kyle']='Mars Brands'
drivers['Matt']='Husky'
drivers['Bobby']='Kingsford'
drivers['Clint']='5-Hour Energy'

我意识到驱动程序字典很长(可能有更简单的方法来添加所有这些驱动程序)。我需要在一个列表(或字典,在这种情况下)中添加 20 位车手和他们的赞助商。将它们简单地添加到类中而不是使用 for 循环会更容易吗?有没有办法添加司机姓名和赞助商作为属性,同时使用里程表和速度的默认值?

【问题讨论】:

  • 附带说明,您确实应该与您的大小写保持一致。最好遵循PEP 8 样式:Cardriversself.driver 等。但即使您选择使用不同的样式,也请始终使用您选择的任何样式。

标签: python class dictionary python-3.3


【解决方案1】:

你可以使用:

cars = [car(driver, sponsor) for driver, sponsor in drivers.items()]

这称为列表推导,它创建一个汽车对象列表,每个对象都使用字典中的驾驶员和相应的赞助商(但默认值为里程表和速度)。

【讨论】:

    【解决方案2】:

    我意识到驱动程序字典很长(可能有更简单的方法来添加所有这些驱动程序)。

    是的,您可以使用字典显示:

    drivers = {
        'David': 'Burger King',
        'Travis': 'Dr Pepper',
        # ...
    }
    

    有没有办法添加司机姓名和赞助商作为属性,同时使用里程表和速度的默认值?

    是的。事实上,你已经做到了。您定义car.__init__ 的方式,您只需省略其他两个参数,它们将获得默认值:

    >>> david = car('David', 'Burger King')
    >>> david.Driver
    'David'
    >>> david.Odometer
    0
    

    所以,现在您所缺少的只是一种从您的 drivers 字典中创建 20 个 car 实例的方法。

    假设您想要一个将驱动程序名称映射到 car 实例的 dict,请使用字典推导:

    cars = {driver: car(driver, sponsor) for driver, sponsor in drivers.items()}
    

    或者,如果您只想要 listcar 实例,请改用列表推导:

    cars = [car(driver, sponsor) for driver, sponsor in drivers.items()]
    

    另一件事:按照您定义 car.__init__ 的方式,您为每辆车的速度使用了一个随机数:

    def __init__(self, Driver, Sponsor, Odometer=0,Speed=randint(1,121)):
    

    当 Python 评估此函数定义时,它将调用 randint(1,121) 并将结果作为每次调用该函数的默认值。

    你想要的大概是这样的:

    def __init__(self, Driver, Sponsor, Odometer=0, Speed=None):
        if speed is None:
            speed = randint(1,121)
    

    最后,您的update 方法需要采用self 参数,并且它需要使用它来访问或修改对象的属性,就像您的__init__ 方法一样:

    def update(self):
        self.Odometer = self.Odometer + self.Speed*0.17
        self.Speed = randint(1,121)
    

    从 cmets 看来,您唯一需要做的就是重复循环遍历所有车辆,然后在最后搜索获胜者。为此,您不需要汽车的字典,只需一个列表。所以:

    cars = [car(driver, sponsor) for driver, sponsor in drivers.items()]
    

    现在,这是你每分钟都在做的事情:

    for car in cars:
        car.update()
    

    然后,最后,获胜者是:

    winner = max(cars, key=operator.attrgetter('Odometer'))
    

    max 函数与 Python 中的大多数排序和搜索函数一样,采用可选的 key,它是一个告诉它排序或搜索依据的函数。 attrgetter(name) 是一个函数调用,它返回一个函数,该函数为任何对象获取名为 name 的属性。详情请见Sorting Mini-HOW TO

    为了比较,让我们明确地写出那部分:

    winner = None
    for car in cars:
        if winner is None or car.Odometer > winner.Odometer:
            winner = car
    

    【讨论】:

    • 如果我理解正确,使用 dict 理解将驱动程序列表映射到汽车类中的 Driver 和 Sponsor 属性,并将使用 Driver 名称作为 self,对吗?所以我应该能够调用像 David.car 这样的汽车对象或使用 David.Odometer 检查里程表?就操作数据而言,dict 理解相对于列表理解有什么优势?感谢您花时间和精力帮助教育。非常感谢!
    • @JustinDay:使用字典推导将每个驱动程序(类似"David" 的字符串)映射到car 对象(具有DriverSponsor 属性,以及@987654353 @ 和 Speed 属性)。你没有得到一个名为Davidcar 实例,但你确实得到了一个名为cars["David"] 的汽车实例。
    • @JustinDay:使用字典而不是列表的好处是你有这个映射。否则,您只会得到一个名为 cars[0] 的汽车实例。如果您不需要知道哪辆车是 David 的,哪辆车是 Travis 的等等,而您只需要一个可以循环遍历的所有汽车的列表,那么列表会更好。如果您需要知道 David 的车是哪辆车,最好听听。
    • 最后:当然你可以总是写David = cars["David"]。但你可能不想这样做。通常,当您有 20 多个对象时,您不想要 20 多个变量,您需要一个包含 20 多个成员的单个集合(dict 或列表,视情况而定)。当然,细节取决于你的代码对这些对象做什么,所以如果没有看到更多代码(或伪代码),很难更具体。
    • 啊哈!这很有意义。 dict comprehension 将是在这种情况下使用的工具,因为我需要每分钟更新每辆车的里程表和速度,然后我需要检查里程表>500,这将确定获胜者比赛。因此,如果有意义的话,我将需要能够打印出赢得比赛的汽车对象。我知道我在看一个 for 循环(我讨厌那些)。
    【解决方案3】:

    这里有一些问题:

    • Speed 指的是一个局部变量。在car.update 中,Speed 未定义。 self.Speed 就是你要找的。​​li>
    • def __init__(self, ..., Speed=randint(1,121)): 将给予所有车手相同的随机启动速度。
    • car.update 需要传递一个 self 参数。

    我会这样做:

    import random
    import time
    
    drivers = {
        'David': 'Burger King',
        'Travis': 'Dr Pepper',
        'Landon': 'Precon Marine',
        'Jamie': 'Cessna',
        'Juan': 'Target',
        'Ken': 'Federated Auto Parts',
        'Timmy': 'OXYwater',
        'Josh': 'MDS Transport',
        'Kurt': 'Furniture Row',
        'Casey': 'Geico',
        'Kasey': 'Farmers Insurance',
        'Jeff': 'Axalta',
        'Jimmie': 'Lowes',
        'Dale': 'National Guard',
        'Mike': 'Plinker Tactical',
        'Denny': 'FedEx',
        'Kyle': 'Mars Brands',
        'Matt': 'Husky',
        'Bobby': 'Kingsford',
        'Clint': '5-Hour Energy'
    }
    
    class Car(object):
        def __init__(self, driver, sponsor, odometer=0, speed=None):
            self.driver = driver
            self.sponsor = sponsor
            self.odometer = odometer
    
            if speed is None:
                self.speed = random.randint(1, 121)
            else:
                self.speed = speed
    
        def update(self):
            self.odometer += self.speed * 0.17
            self.speed = random.randint(1, 121)
    
    if __name__ == '__main__':
        cars = []
    
        for driver, sponsor in drivers.items():
            car = Car(driver, sponsor)
            cars.append(car)
    

    你可以写这部分:

        if speed is None:
            self.speed = random.randint(1, 121)
        else:
            self.speed = speed
    

    更简洁如下:

        self.speed = speed or random.randint(1, 121)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 2020-04-12
      • 2018-10-19
      • 1970-01-01
      相关资源
      最近更新 更多