4

这是我一直在努力的一个项目的一部分。我很难将心理伪代码与我可以实际编写的东西综合起来,这主要是由于个人对事物如何工作的误解。

我正在使用以下类跟踪虚构水果摊的库存:

class Fruit(object)
    def __init__(self,name,qty,price)
        self.color = str(color)
        self.qty = int(qty)
        self.price = float(price)

    def getName(self): return self.color
    def getQty(self): return self.qty
    def getPrice(self): return self.price
    def description(self): return self.color,self.qty,self.price

此类中的对象最终被导入为字典键的值。每个键可以有多个值,存储在一个列表中,这样当打印字典时,它会返回类似这样的内容(为了可读性而使用换行符:)

Lemon: [(Yellow, 5, 2.99)]
Apple: [(Red, 10, 0.99), (Green, 9, 0.69)]
Cherry: [(White, 2, 5.99),(Red, 5, 5.99)]

我现在正试图最终得到我想象中的水果摊上所有水果的总价值。我最初的想法只是将每个值视为一个列表,遍历列表直到我找到一个整数,将整数乘以它后面索引中的浮点数,然后将该数量添加到具有运行总计的变量中;然后继续寻找另一个整数。如果列表“Cherry”的“索引 1”不是 (Red, 5, 5.99) 而不是 (2),这会很好用。

所以,有几个问题。

  1. 每次我做这样的事情时,我有一个包含多个值的字典,这些值都是类对象,每个值都存储为括号(因为没有更好的方法来调用它。)这是应该发生的事情,还是我是否需要重新评估我正在做的事情的方式,因为我正在导致这种情况发生?

  2. 如果我不需要在这里重新评估我的选择,有没有办法打破“括号”(因为没有更好的东西可以立即想到它们)以便能够将整个事情视为列表?

  3. 有没有更好的方法来做我想做的不涉及遍历列表的事情?

提前致谢。一个星期以来,我一直在与这个问题的各个部分作斗争。

4

3 回答 3

6

假设像这样的字典:

fruit_stand = {
    "Lemon": [(Yellow, 5, 2.99)],
    "Apple": [(Red, 10, 0.99), (Green, 9, 0.69)],
    "Cherry": [(White, 2, 5.99),(Red, 5, 5.99)]
}

您实际上可以遍历字典以获取其键:

for fruit_name in fruit_stand:
    print fruit_name

# Lemon
# Apple
# Cherry
# NOTE: Order not guaranteed
# Cherry, Lemon, Apple are equally likely

然后,您可以使用字典的方法来获取,items对的元组(您称之为“括号”):keyvalue

for fruit_name, fruits in fruit_stand.items():
    print fruit_name, "=>", fruits

# Lemon => [(Yellow, 5, 2.99)]
# Apple => [(Red, 10, 0.99), (Green, 9, 0.69)]
# Cherry => [(White, 2, 5.99),(Red, 5, 5.99)]

lists (即括号内的[])也是可迭代的:

for fruit in [(White, 2, 5.99),(Red, 5, 5.99)]:
    print fruit

# (White, 2, 5.99)
# (Red, 5, 5.99)

所以我们可以使用每个fruits列表来访问我们的tuple

for fruit_name, fruit_list in fruit_stand.items():
    # Ignore fruit_name and iterate over the fruits in fruit_list
    for fruit in fruit_list:
        print fruit

正如我们所见,items我们可以将元组解包为多个值:

x, y = (1, 2)
print x
print y
# 1
# 2

所以我们可以将每一个解压fruit成它的组成部分:

for fruit_name, fruit_list in fruit_stand.items():
    # Ignore fruit_name and iterate over the fruits in fruit_list
    for color, quantity, cost in fruit_list:
        print color, quantity, cost

然后得到总数并不难:

# We need to store our value somewhere
total_value = 0
for fruit_name, fruit_list in fruit_stand.items():
    # Ignore fruit_name and iterate over the fruits in fruit_list
    for color, quantity, cost in fruit_list:
        total_value += (quantity * cost)

print total_value

话虽如此,有清晰的做事方式:

  1. 您可以使用列表推导来简化for循环:

    for fruit_name in fruit_stand
        operation(fruit_name)
    

    可以翻译成这个列表理解:

    [operation(fruit_name) for fruit_name in fruit_stand]
    

    因此,我们可以将嵌套for循环翻译成:

    sum([cost * quantity \  # Final operation goes in front
        for _, fruits in fruit_stand.items() \
            for _, cost, quantity in fruits])
    

    因为我们实际上并不需要列表,所以我们可以摆脱它,Python 将为我们创建一个生成器:

    sum(cost * quantity \  # Note the missing []
        for _, fruits in fruit_stand.items() \
            for _, cost, quantity in fruits)
    
  2. 您可以添加一个__add__方法,Fruit以便将两组水果加在一起给出两组的总成本Fruit(但您可能希望创建一个中间数据结构来做到这一点,也就是说Basket不必Fruit担心quantity哪个不'不真正属于Fruit,除非 的任何实例Fruit具有内在数量 1。我省略了此选项的代码,因为此答案已经太长了。

于 2013-05-01T01:38:12.683 回答
4

您要查找的词是"tuple"。这些“括号”是元组

Python 的主要优势之一是其用于迭代列表的紧凑语法。您可以在一行中计算每种水果的价格总和:

>>> fruit = [("Red", 10, 0.99), ("Green", 9, 0.69)]
>>> sum(qty * price for color, qty, price in fruit)
16.11

分解它,里面的东西sum()叫做生成器表达式for color, qty, price in fruit迭代fruit并将元组解包为三个命名变量。然后可以在for. 对于fruit列表中的每个元组,生成器表达式计算qty * price.

如果你把这个表达式放在方括号内,它就变成了一个列表推导,让你看到计算出来的值。

>>> [qty * price for color, qty, price in fruit]
[9.9, 6.209999999999999]
于 2013-05-01T01:17:17.103 回答
1

我会首先放弃这些returnFoo方法,因为它的输入时间更短apple.price

class Fruit(object)
    def __init__(self, name, qty, price)
        self.color = str(color)
        self.qty = int(qty)
        self.price = float(price)

如果您不接受任意输入,例如qty='100',您也不需要类型转换:

class Fruit(object)
    def __init__(self, name, qty, price)
        self.color = color
        self.qty = qty
        self.price = price

你剩下的是一个除了存储值什么都不做的类。在这种情况下,我只会使用字典:

fruit = {
    'color': 'red',
    'qty': 1000,
    'price': 1.99
}

要将成本加起来,您首先需要水果:

fruits = [{
    'color': 'red',
    'qty': 1000,
    'price': 1.99
}, {
    'color': 'blue',
    'qty': 100,
    'price': 15.99
}, {
    'color': 'orange',
    'qty': 10,
    'price': 5.99
}]

然后你可以使用一个for循环:

total = 0

for fruit in fruits:
    total += fruit['qty'] * fruit['price']

可以使用sum生成器表达式进一步简化:

total = sum(fruit['price'] * fruit['qty'] for fruit in fruits)

另一种方法是使用FruitStand类和你原来的Fruit类:

class FruitStand(object):
    def __init__(self, fruits=None):
        self.fruits = fruits or []

    def totalCost(self):
        return sum(fruit.price * fruit.qty for fruit in self.fruits)
于 2013-05-01T01:26:03.757 回答