首页 > 解决方案 > TypeError:“str”对象在尝试创建嵌套字典时不支持项目分配

问题描述

我有几个列表,我试图遍历并创建一个基于键的嵌套字典(在本例中为日期)。这些列表来自一个数据框,这是我的做法,但我收到了上面的错误。这个想法是获取“日期”列表中每个日期的每种面包的“总计”和“体积”值。列表的顺序是一致的,并且它们具有相同的长度。知道为什么会这样吗?目标是分析/可视化从 2018 年至今的销售业绩我有一个想法,嵌套字典可能不是最好的解决方案,所以欢迎任何更好的想法。

我的数据结构:

 ID      Created At                 Description                   Order No  Qnty StockID Price  Total  Date
233535  2020-05-30 19:12:17+03:00   SLICED ROUND TOP WHITE BREAD    71231   285 FG003   36.0    10260.0 2020-05-30
233537  2020-05-30 19:12:17+03:00   SLICED ROUND TOP BROWN BREAD    71231   15  FG004   36.0    540.0   2020-05-30
233529  2020-05-30 19:11:18+03:00   SLICED ROUND TOP WHITE BREAD    71229   90  FG003   36.0    3240.0  2020-05-30
233531  2020-05-30 19:11:18+03:00   SLICED ROUND TOP BROWN BREAD    71229   10  FG004   36.0    360.0   2020-05-30

breads=[]
dates=[]
volumes=[]
totals=[]
for i, row in sales.iterrows():
    bread=row[2]
    breads.append(bread)
    vol=row[4]
    volumes.append(vol)
    total=row[-2]
    totals.append(total)
    date=row[-1]
    dates.append(date)

from collections import defaultdict

sku_vol_total_by_date=defaultdict(dict)
for i in range(len(dates)):
    date=dates[i]
    bread=breads[i]
    volume=volumes[i]
    total=totals[i]
    if date not in sku_vol_total_by_date.keys():
        sku_vol_total_by_date[date]=date
        sku_vol_total_by_date[date][volume]=volume
        sku_vol_total_by_date[date][total]=total
    else:
        sku_vol_total_by_date[date][bread][volume]+=volume
        sku_vol_total_by_date[date][bread][total]+=total

sku_vol_total_by_date

标签: pythonpandasnumpy

解决方案


您尝试实现嵌套字典的方式存在问题。

首先,您正在使用sku_vol_total_by_date=defaultdict(dict),这是一个默认字典,其值是常规字典,因此您将无法使用多个嵌套深度。但是,您使用字典的方式存在更深层次的问题。

Defaultdicts 通过根据 defaultdict 的类型(在您的情况下为 dict)用默认值填充缺失的条目来工作。因此,即使您从未为键“test”添加条目,以下操作也将起作用:

sku_vol_total_by_date=defaultdict(dict)
print(sku_vol_total_by_date["test"])  # will print the empty dict {}

但是,如果您手动将键/值对添加到 defaultdict,它将使用您提供的任何值:

sku_vol_total_by_date=defaultdict(dict)
sku_vol_total_by_date["test"] = "test_string"
print(sku_vol_total_by_date["test"])  # will print "test_string"

由于您显式地将字符串值添加到字典中,python 将忽略您已将默认值定义为 dict 的事实,并接受您放入字典中的任何内容。

开始嵌套时会出现问题。在前面的示例中,字典包含一个键/值对"test": "test_string"

因此,如果您这样做,它将失败并显示您给出的错误消息:

sku_vol_total_by_date["test"]["new_test"] = "new_test_string"

该表达式sku_vol_total_by_date["test"]与“test_string”相同,因此您基本上是在尝试编写

"test_string"["new_test"] = "new_test_string"

这在 python 中被解释为类似于 的东西mystring[3] = "x",这对于字符串是不允许的。

那么,从这里到哪里去呢?嵌套的 defaultdicts 在这里描述:Nested defaultdict of defaultdict

阅读您的代码,我得到的印象是嵌套字典不是解决您的问题的方法。如果不确切知道您的数据的结构,很难说这是一个好的解决方案。我假设您想对属于同一“日期”的所有“音量”数字进行分组,并对“总”数字做同样的事情。

一个让你上路的提示,因为这看起来像一个家庭作业,我不想放弃答案:分组值可以用 defaultdict(int) 来完成,你可能需要单独的字典来为你的“卷" 和 "总" 值。尝试研究一些关于 defaultdicts 以及它们通常如何使用的例子。


推荐阅读