【问题标题】:Dictionary won't store the value after restart重新启动后字典不会存储值
【发布时间】:2015-02-04 09:02:59
【问题描述】:

这是我的代码。此代码用于管理商店中的水果库存。所以你输入水果的名称和数量。如果水果没有在字典中注册,它会将水果和它的值添加到字典中。如果水果被注册,它会检查它的值是否大于字典中的原始值。如果它更大,它将替换金额,但如果输入的金额小于原始金额,它不会做任何事情。

我使用下面的代码来检查水果的平均值。所以它会计算我买了多少水果并累积起来。这样以后,我就可以用它来找出平均值,方法是用这个数字除以我积累的次数。

items[fruit_t]["av"]+=(fruit_n)

这是一个问题。每当我尝试将内容添加到字典时,它都会第一次打印,但是当我继续添加另一个水果时,之前添加的水果会消失。我不明白出了什么问题。另外,我想使用 .append 而不是 += ,如上所示,但是当我尝试这样做时,会出现错误。我想使用 append 因为稍后,我可以使用 len() 来计算 av 中有多少数字 , 将 av 相加并除以 av 的 len() 值。

    import pickle
    def fruit():
        with open('fruits.pickle', 'a') as f:
            try:
                items = pickle.load(f)
            except ValueError:
                items = {"Apple":{"av":10,"count":10},"Banana":{"av":14,"count":14},"Orange":{"av":23,"count":23},"Watermelon":{"av":54,"count":54}}
            fruit_t = input("Please type in the name of the fruit: ")
            fruit_n = int(input("Please type in the amount of the fruit: "))
            if fruit_t in items:
                items[fruit_t]["av"]+=(fruit_n)
                if items[fruit_t]["count"] < fruit_n:
                    items[fruit_t]["count"] = fruit_n
            else: 
                items[fruit_t] = {"av":fruit_n,"count":fruit_n}
            with open('fruits.pickle', 'wb') as f:
                pickle.dump(items, f)
            for k in items:
                print("{} monthly  {}".format(k,items[k]["av"]))
                print("{} total {}".format(k,items[k]["count"]))
            fruit()

    fruit()

编辑和工作代码。

    import pickle
def fruit():
    with open('fruits.pickle', 'rb') as f:
        try:
            items = pickle.load(f)
        except ValueError:
            items = {}
        fruit_t = input("Please type in the name of the fruit: ")
        fruit_n = int(input("Please type in the amount of the fruit: "))
        if fruit_t in items:
            items[fruit_t]["total"]+=(fruit_n)
            if items[fruit_t]["count"] < fruit_n:
                items[fruit_t]["count"] = fruit_n
        else: 
            items[fruit_t] = {"total":fruit_n,"count":fruit_n}
        with open('fruits.pickle', 'wb') as f:
            pickle.dump(items, f)
        for k in items:
            print("{} monthly  {}".format(k,items[k]["total"]))
            print(items[k]["count"])
        fruit()

fruit()

【问题讨论】:

  • 1) 查看集合模块中的 Counter-class (docs.python.org/2/library/collections.html)。 2)你的缩进似乎很遥远。就像现在一样,您正在递归调用fruit(),没有破坏条件,并且您正在上下文管理器中重新打开fruits.pickle
  • @MrGumble 如果您能提供帮助,是否可以改进此代码?

标签: python dictionary pickle


【解决方案1】:

我会用一种非常不同的方式回答你的问题:

pickle 不会加载您的腌制文件,因为您在第 3 行以“附加”模式打开文件。 您没有注意到错误,因为您已将加载包含在 try-statement 中。相反,会捕获异常并从默认值加载您的 items

解决方案:将第 3 行 open 中的模式更改为 rb

【讨论】:

  • 哦,现在我已经改了。现在我只需要找出如何用 av 获得平均值
  • 要计算平均值,只需跟踪count 的运行总和以及您“购买”某物的次数。然后,平均值是总和除以购买次数。要永久存储,可以使用泡菜,但由于酸洗协议可能会发生变化,因此不是最佳解决方案。改用基于文本的文件来长期存储您的结果。
  • 可以使用 csv 吗?请问你能用pickle/text文件实现你的代码吗?谢谢
  • 没有。您的代码已经在挑选结果,使用文本文件完全取决于您未来对数据的使用。
【解决方案2】:

鉴于您没有更正问题中的代码,这就是问题所在:

  1. 您在第 3 行的 open 中指定了“附加”作为模式。 这在您打算读取文件时没有用;改为使用 r 用于读取,rb 用于读取二进制文件。
  2. 删除第 8 行 (fruit_t = ...),因为这标志着从第 3 行开始退出上下文管理器(with ... 是上下文管理器)。这将再次关闭文件,因为您已完成阅读。紧跟以下几行。
  3. 您不需要跟踪每个“购买”;您可以改为依靠 1) 购买总和 2) 购买计数。计算平均值非常容易。因此,您可以将字典一分为二。
  4. 在第 12 行,我无法理解您的逻辑,并且与您在问题中写的内容相矛盾。

代码示例 1

from collections import Counter

fruits = {'apple':0, 'banana':0}
purchases = Counter(fruits)
fruits = Counter(fruits)
## on purchase
fr = 'apple'
buy = 4
fruits[fr] += 4
purchases[fr] += 1

看看如果您购买的水果还没有出现在柜台(即设置fr = 'mandarin')会发生什么。

【讨论】:

  • 所以这在技术上是实现我想要做的事情的更好方法?
  • 当我尝试这段代码时,这不会添加以前的值。所以它不存储任何东西。
  • 您将不得不详细说明“这不会添加先前的值”的含义。在哪种情况下?
  • 从技术上讲,更好的方法取决于您的总体目标是什么。你为什么要腌制你的字典?
  • 因为我希望将数据存储在 pickle 文件中,而不是代码中。我原本打算在 csv 中执行此操作,但有人告诉我在 pickle 中执行此操作,所以我在 pickle 中执行此操作。
猜你喜欢
  • 2018-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
相关资源
最近更新 更多