如何对集合列表求和?在 class 中使用字符串和整数?

How to sum a list of sets? with strings and integers in a class?

我是 python 编程的新手,我正在学习 python 4 everybody 课程。为此,我需要构建一个预算应用程序。具体来说就是前两个任务:

完成 budget.py 中的类别 class。它应该能够根据不同的预算类别(如食物、衣服和娱乐)实例化对象。创建对象时,它们以类别的名称传递。 class 应该有一个名为 ledger 的实例变量,它是一个列表。 class 还应包含以下方法:

一个接受金额和描述的存款方法。如果没有给出描述,它应该默认为一个空字符串。该方法应以 {"amount": amount, "description": description} 的形式将对象附加到分类帐列表。

一个withdraw方法,与存款方法类似,但传入的金额应以负数形式存储在账本中。如果没有足够的资金,则不应将任何内容添加到分类帐中。如果发生提款,此方法应 return True,否则为 False。

我目前的尝试如下:

class Category:
    def __init__(self):
        self.ledger = []
        Total = 0

    def deposit(self, amount, *description):
        self.ledger.append({"amount": amount, "description": description})
              
        return self.ledger

    def withdraw(self, withdrawal):
        
        for x in self.ledger:
            if x == int():
                return sum
            
        self.ledger.append({"withdrawal": withdrawal})
        
        return self.ledger

我想我有多个问题:

  1. 什么是将 {} 作为一个项目的列表?是5.4吗? "Set"?
  2. 现在如何实现withdraw方法的需求“如果没有足够的资金,不应该添加任何东西到账本中。”我想我需要对列表 self.ledger 中的所有整数求和,但不知道如何从中获取这些整数并求和。我试过了,你可以看到一个 for 循环,但我认为这是不正确的语法?

非常感谢您的帮助,也感谢您提供一些背景知识!

提前致谢! 卢卡斯

所以,有些事情需要澄清。

  1. self.ledger = [][]部分使账本成为列表,self.部分成为实例变量,仅适用于class的特定实例类别
  2. 如评论中所述,{"key": "value"} 是一个字典对象。使用 self.ledger.append({"key": "value"}) 将字典对象 {"key": "value"} 添加到分类帐列表。
  3. 通常情况下,如果您想跟踪 class 中的数字,您可以创建一个实例变量并在它发生变化时更新它。请参阅下面 self.total 的用法。
  4. 重新计算总数也可以,见下面的方法update_total()

我在下面添加了一些测试。

class Category:
    def __init__(self):
        self.ledger = []
        # total also needs the "self." to make it an instance variable, just
        # as the ledger above
        # if you omit the "self."" it's a localized variable only available
        # to the __init__ method itself.
        self.total = 0

    def deposit(self, amount, *description):
        self.ledger.append({"amount": amount, "description": description})
        # add the amount to the total
        self.total += amount
        return self.ledger

    def withdraw(self, withdrawal):
        # make the withdrawal negative
        if abs(withdrawal) == withdrawal:
            withdrawal = 0 - withdrawal
        # check if there's enough in the total
        if abs(withdrawal) <= self.total:
            # update the total
            self.total += withdrawal
            # add to the ledger
            self.ledger.append({"withdrawal": withdrawal})
        else:
            # you could return an error message here
            pass
        return self.ledger

    def update_total(self):
        total = 0
        for item in self.ledger:
            # need to check if the amount key is in the dict object
            if "amount" in item:
                total += item["amount"]
            # this check below is not needed but it ensures future compatability
            elif "withdrawal" in item:
                total += item["withdrawal"]
        # just because, you can check if the totals match
        if self.total != total:
            print(
                f"""Difference in totals found. Someone is cheating :-|
  Instance total:   {self.total}
  Calculated total: {total}"""
            )
        # set the instance variable to the local variable
        self.total = total
        return self.total



from pprint import pprint
nr1 = Category()
nr2 = Category()

for i in range(10):
    nr1.deposit(i, f"deposit - {i}")

pprint(nr1.ledger)
print(f"Total: {nr1.total}")
nr1.withdraw(10)
print(f"Total: {nr1.total}")
nr1.withdraw(-10)
print(f"Total: {nr1.total}")
nr1.withdraw(99999)
print(f"Total: {nr1.total}")
pprint(nr1.ledger)
print(nr1.update_total())
nr1.total = 123
print(nr1.update_total())

# just to show that the above only updated the values inside the nr1 instance.
print(f"Total for nr2: {nr2.total}")
  1. {} 是空字典。一个空集是 set()

  2. 提取函数应该这样做:

     def withdraw(self, amount, description):
    
         balance = sum(transaction["amount"] for transaction in self.ledger)
    
         if balance >= withdrawal :
             self.ledger.append({"amount": -amount, "description": description})
             return True
         else :
             return False
    
     return self.ledger
    

这使用生成器作为内置求和函数的参数。如果您刚刚开始,这可能有点高级 python,因此您还可以使用更适合初学者的代码计算余额:

    balance = 0
    for transaction in ledger:
        balance = balance + transaction["amount"]
        # you can shorten the line above to
        # balance += transaction["amount"]

这大致相当于 sum 和生成器语法所做的。

出于好奇,deposit 函数中 description 参数前面的 * 是拼写错误吗?