鱼C论坛

 找回密码
 立即注册
查看: 3901|回复: 155

[已解决]字典嵌套列表,列表元素为字典,添加列表元素后报错

[复制链接]
发表于 2023-12-7 20:34:04 | 显示全部楼层 |阅读模式
10鱼币
大家好,我有个问题想请教一下:

我写代码时设置了一组"字典-列表-字典"的嵌套结构,部分代码如下:
sym = tos[3].split('=')[1]       #这部分是从一个日志文件里读取到的数据,
这段代码的目的主要是把读取到的 字典sjz作为一个元素添加到一个空列表里,出现的问题是运行过程中报错,提示keyerror:
111.JPG

请问为什么会出现这样的问题呢?
我以为要么是直接报错,要么就应该正常运行,为什么会运行到中途报错呢?

我觉得应该是这句代码引起的问题,因为当我注释掉这句话之后,就没有报错了
data[sym].append(sjz)
但我确实找不出哪儿出了问题,麻烦各位大大帮忙看下,感激不尽!

注释掉添加代码后,可以正常提取字典key值

注释掉添加代码后,可以正常提取字典key值


因为全部的代码需要搭配文本文件才能正常运行,而文本文件又太大了,不方便传上来,也就没有全部贴上来,还望理解。



最佳答案
2023-12-7 20:34:05
你好!根据你提供的信息,可以推测出问题可能出在以下几个地方:

1. `tos` 变量没被正确赋值导致 `split` 函数无法正常工作。

2. `tos` 被正确赋值了,但是其中不包含等号`=`,导致 `split` 函数返回的列表中只有一个元素。

3. `sjz` 字典在添加到列表时没有使用正确的键,导致出现 `KeyError`。


下面是一个简单的示例来模拟你的问题,并给出解决方案:
tos = "name=Tom"  # 模拟从日志文件中读取的数据sym = tos.split('=')  # 使用等号进行切割# 创建一个空字典和一个空列表sjz = {}lst = []# 判断切割结果是否正常if len(sym) == 2:    sjz[sym[0]] = sym[1]  # 将切割结果添加到字典中    lst.append(sjz)  # 将字典添加到列表中    print(lst)else:    print("切割结果不正确")
在这个示例中,我们使用 `=` 进行字符串 `tos` 的切割,并将切割后的结果添加到字典 `sjz` 中。然后再将 `sjz` 添加到列表 `lst` 中。如果切割结果正确,那么最终输出的 `lst` 就是我们期望的结果。

注意,示例中对于切割结果进行了简单的判断,如果 `sym` 的长度不等于 2,则说明切割结果不正确。你可以根据实际情况对切割结果进行更详细的判断和处理。

希望对你有帮助!如还有问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

最佳答案

查看完整内容

你好!根据你提供的信息,可以推测出问题可能出在以下几个地方: 1. `tos` 变量没被正确赋值导致 `split` 函数无法正常工作。 2. `tos` 被正确赋值了,但是其中不包含等号`=`,导致 `split` 函数返回的列表中只有一个元素。 3. `sjz` 字典在添加到列表时没有使用正确的键,导致出现 `KeyError`。 下面是一个简单的示例来模拟你的问题,并给出解决方案: 在这个示例中,我们使用 `=` 进行字符串 `tos` 的切割,并将切割后的 ...

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 20:34:05 | 显示全部楼层    本楼为最佳答案   
你好!根据你提供的信息,可以推测出问题可能出在以下几个地方:

1. `tos` 变量没被正确赋值导致 `split` 函数无法正常工作。

2. `tos` 被正确赋值了,但是其中不包含等号`=`,导致 `split` 函数返回的列表中只有一个元素。

3. `sjz` 字典在添加到列表时没有使用正确的键,导致出现 `KeyError`。


下面是一个简单的示例来模拟你的问题,并给出解决方案:
tos = "name=Tom"  # 模拟从日志文件中读取的数据sym = tos.split('=')  # 使用等号进行切割# 创建一个空字典和一个空列表sjz = {}lst = []# 判断切割结果是否正常if len(sym) == 2:    sjz[sym[0]] = sym[1]  # 将切割结果添加到字典中    lst.append(sjz)  # 将字典添加到列表中    print(lst)else:    print("切割结果不正确")
在这个示例中,我们使用 `=` 进行字符串 `tos` 的切割,并将切割后的结果添加到字典 `sjz` 中。然后再将 `sjz` 添加到列表 `lst` 中。如果切割结果正确,那么最终输出的 `lst` 就是我们期望的结果。

注意,示例中对于切割结果进行了简单的判断,如果 `sym` 的长度不等于 2,则说明切割结果不正确。你可以根据实际情况对切割结果进行更详细的判断和处理。

希望对你有帮助!如还有问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-7 20:37:05 | 显示全部楼层
发完帖子我忽然注意到一个问题,报错的时候,在提取5个INTZ.NQ后提示的是KeyError: 'HRTX.NQ',但是注释掉append语句后,同样的位置,5个INTZ.NQ后面的内容还是INTZ.NQ,而不是HRTX.NQ,会不会是因为我的文本文档数据有问题呢?我再去检查一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 20:37:41 | 显示全部楼层
wrpython 发表于 2023-12-07 20:37
发完帖子我忽然注意到一个问题,报错的时候,在提取5 ...

嗯,你的怀疑是正确的,问题可能出在你的文本文件数据上。在你的帖子中提到的报错信息是 "KeyError: 'HRTX.NQ'",这意味着在字典中没有找到键为 'HRTX.NQ' 的项。如果你注释掉了 `append` 语句后,同样的位置显示的是 'INTZ.NQ',而不是 'HRTX.NQ',那很有可能是你的文本文件数据导致了这个问题。

建议你仔细检查文本文件中的数据,确保它们的格式和内容符合你的预期。确认一下是否存在键为 'HRTX.NQ' 的项,以及其他数据是否存在类似的问题。

此外,你也可以尝试打印出分割后的 `sym` 变量,检查它们的值是否与你期望的一致。例如:
print(sym)
这样可以帮助你进一步排查问题所在。

祝你好运,希望能找到问题所在并解决它!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-7 22:25:04 | 显示全部楼层
FishC 发表于 2023-12-7 20:37
嗯,你的怀疑是正确的,问题可能出在你的文本文件数据上。在你的帖子中提到的报错信息是 "KeyError: 'HRT ...

检查了一遍原始数据,文本数据的格式是正确的,在报错的那一行,文本格式没有问题。问题在别的地方
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 22:25:45 | 显示全部楼层
wrpython 发表于 2023-12-07 22:25
检查了一遍原始数据,文本数据的格式是正确的,在报错 ...

如果你确认了原始数据的格式没有问题,那么报错的原因很可能与其他地方有关。以下是一些可能导致问题的原因和解决方法:

1. 确保字典 `sjz` 是在每次迭代之前重置为空字典。在遍历数据并创建新的字典时,确保在每次迭代之前将 `sjz` 字典重置为空字典。这样可以确保每个迭代都创建一个新的字典,并避免将相同的字典多次添加到列表中。

示例代码:
lst = []  # 创建一个空列表# 遍历数据for tos in data:    sym = tos.split('=')  # 使用等号进行切割        if len(sym) == 2:        sjz = {}  # 每次迭代前重置 sjz 字典为空字典        sjz[sym[0]] = sym[1]  # 将切割结果添加到字典中        lst.append(sjz)  # 将字典添加到列表中print(lst)
2. 确保变量 `data` 包含正确的数据。请确保变量 `data` 包含正确的数据,并且每行数据都按照预期的格式进行分割。

3. 检查是否存在其他代码逻辑错误。除了上述的问题之外,还可能存在其他代码逻辑错误导致报错。请仔细检查代码的其他部分,例如遍历数据的循环、条件判断等是否正确。

这些是常见的可能导致问题的原因和解决方法。希望能帮助你找到问题所在并解决它!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-7 23:00:24 | 显示全部楼层
我又重新试了一遍,我发现不使用print语句,程序也不会报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 23:00:54 | 显示全部楼层
wrpython 发表于 2023-12-07 23:00
我又重新试了一遍,我发现不使用print语句,程序也不 ...

如果你发现不使用 print 语句,程序没有报错,这意味着问题可能出现在你对程序的理解上。在 Python 中,print 语句用于将变量的值输出到控制台,以便我们查看程序的执行结果。如果你没有使用 print 语句,那么程序可能仍然执行了,但你无法直接观察到结果。

为了更好地理解代码的执行过程,你可以尝试使用 print 语句来输出关键变量的值。这样可以帮助你确定代码是否按照预期进行了处理。

另外,还有一种可能是虽然程序没有报错,但它可能并没有按照你的预期工作。这可能是因为某些逻辑错误导致的。在这种情况下,你可以使用调试工具,例如PyCharm、VS Code等,逐行跟踪代码的执行流程,以便找出问题所在。

如果你愿意提供更多的代码和具体的错误信息,我会更好地帮助你解决问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-7 23:08:28 | 显示全部楼层
问题在代码中的data[sym], 因为我用一个变量名替换掉data[sym],程序就可以正常运行了,使用print语句也没有问题,但是如果直接用data[sym],程序运行到某一个位置时就会报出keyerror的错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 23:09:08 | 显示全部楼层
wrpython 发表于 2023-12-07 23:08
问题在代码中的data, 因为我用一个变量名替换掉data ...

如果你发现问题出现在代码中的 `data` 变量上,可能是因为 `data` 中的某些数据导致了 `KeyError` 的错误。`KeyError` 错误通常表示字典中不存在指定的键。根据你的描述,可能是在遍历 `data` 数据的过程中,有些数据的键没有正确地添加到字典中,导致后续操作出现 `KeyError` 错误。

解决这个问题的方法有两种:

1. 检查原始数据:检查一下原始数据中的键是否按照预期添加到字典中。确保每个键都被正确地添加到字典中,以避免出现 `KeyError` 错误。

2. 添加异常处理:你可以使用 try-except 语句来捕获 `KeyError` 错误,并做出相应的处理。例如,你可以在遇到 `KeyError` 错误时打印出相关信息,以便调试。

下面是一个示例代码,演示了如何使用异常处理来处理 `KeyError` 错误:
lst = []  # 创建一个空列表# 遍历数据for tos in data:    sym = tos.split('=')    try:        if len(sym) == 2:            sjz = {}            sjz[sym[0]] = sym[1]            lst.append(sjz)        else:            print("切割结果不符合预期:", sym)    except KeyError as e:        print("发生了KeyError错误:", e)print(lst)
在这个示例中,我们将主要的代码部分放入了一个 try 块中,并添加了一个 except 块来处理 `KeyError` 错误。当遇到 `KeyError` 错误时,打印出相关信息。

希望以上解决方案对你有帮助!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-7 23:52:03 | 显示全部楼层
FishC 发表于 2023-12-7 23:09
如果你发现问题出现在代码中的 `data` 变量上,可能是因为 `data` 中的某些数据导致了 `KeyError` 的错误 ...

还有一个问题,在使用lst.append(sjz)时,我发现lst不定时的会被清零,有时候是添加了几十个sjz,有时候是添加了几百个sjz,有时候2个sjz,程序里没有包含任何清空lst的语句,为什么lst会被自动清空?而且看起来没有什么规律
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-7 23:57:37 | 显示全部楼层
wrpython 发表于 2023-12-07 23:52
还有一个问题,在使用lst.append(sjz)时,我发现lst不 ...

lst 被不定时地清零的原因可能是由于在遍历 `data` 数据的过程中,出现了某些异常导致程序提前退出循环。这样就会导致列表 `lst` 在下一次循环开始时重新初始化为空列表。如果你想要保留之前已经添加到 `lst` 中的元素,可以将 `lst` 的初始化移到循环外部。以下是修改后的代码示例:
lst = []  # 创建一个空列表# 遍历数据for tos in data:    sym = tos.split('=')        try:        if len(sym) == 2:            sjz = {}            sjz[sym] = sym            lst.append(sjz)        else:            print("切割结果不符合预期:", sym)    except KeyError as e:        print("发生了KeyError错误:", e)print(lst)
在这个示例中,我们将 `lst` 的初始化移到了循环外部,确保每次循环都是从上一次结束的地方继续添加元素,而不是重新初始化。同时,在异常处理中打印出错误信息,以帮助调试报错的具体原因。

希望以上解决方案对你有帮助!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-8 01:01:05 | 显示全部楼层
PYcharm怎么逐行运行查看运行结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-8 01:01:31 | 显示全部楼层
wrpython 发表于 2023-12-08 01:01
PYcharm怎么逐行运行查看运行结果

在 PyCharm 中,你可以使用调试模式逐行运行代码并查看运行结果。以下是一些步骤来执行逐行调试:

1. 打开你的项目,并打开要调试的 Python 文件。
2. 在你想要设置断点的行上,单击行号旁边的空白区域,或者使用快捷键 "Ctrl + F8" 来设置断点。断点会以红色圆点的形式显示在行号处。
3. 单击菜单栏中的 "Run" 或者使用快捷键 "Shift + F9" 来运行程序。PyCharm 会在第一个断点处停下来。
4. 在调试模式下,你可以使用 "Step Over" 按钮(快捷键 F8)逐行运行代码。每次点击该按钮,程序会执行一行,并跳转到下一行。
5. 在代码执行期间,你可以在变量窗口中查看和监视变量的值。通过单击菜单栏中的 "View" > "Tool Windows" > "Debugger" 来打开变量窗口(或者使用快捷键 "Alt + 2")。
6. 当程序执行到断点时,你可以检查代码执行过程中的变量、调用栈等相关信息。

通过逐行调试,你可以更好地了解程序的执行流程,并查看每一步的运行结果。希望这些步骤能帮助你在 PyCharm 中进行逐行调试,并解决问题。如有更多疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-8 01:38:42 | 显示全部楼层
我找到data[sym]会出错的原因了
if sym in stk :
            
            if sym not in jd:
                jd.add(sym)
                ks = now - now%300
                js = ks + 300
                data = {sym:[],'ks':ks,'js':js}
                
            sjz = {'symbol':sym,'price':pri,'size':size,'mmid':mmid,'time':time1,'now':now}
            data[sym].append(sjz)
            print(sjz)
            print(data)

通过print(sjz)和print(data)可以知道报错时两个变量的内容分别是
{'symbol': 'HRTX.NQ', 'price': '0.725', 'size': 100, 'mmid': 'z', 'time': '09:14:11', 'now': 33251}
{'INTZ.NQ': [], 'ks': 33000, 'js': 33300}
sjz中的sym是’HRTX.NQ‘
data[sym]中的sym是’INTZ.NQ‘
所以会报错。

你有什么改进建议呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-8 01:39:05 | 显示全部楼层
wrpython 发表于 2023-12-08 01:38
我找到data会出错的原因了
if sym in stk :
        ...

根据你提供的信息,可以看出问题是因为 `sjz` 字典中的 `sym` 和 `data` 字典中的 `sym` 不一致导致的。要解决这个问题,你可以按照以下方式修改代码:
if sym in stk:    if sym not in jd:        jd.add(sym)        ks = now - now % 300        js = ks + 300        data[sym] = {'ks': ks, 'js': js} # 使用sym作为键,创建data的子字典        sjz = {            'symbol': sym,            'price': pri,            'size': size,            'mmid': mmid,            'time': time1,            'now': now        }        data[sym]['data'] = [] # 在data的子字典中创建一个空的列表        data[sym]['data'].append(sjz) # 将sjz添加到对应的data子列表中        print(sjz)        print(data[sym]['data'])
在上面的代码中,我们使用 `sym` 作为键,将 `data` 的值设置为一个子字典。然后,在子字典中创建一个空的列表 `data[sym]['data']`,并将 `sjz` 添加到该列表中。这样,每个 `sym` 都有自己独立的子字典和对应的列表,避免了不同 `sym` 之间的冲突。

希望这个改进方案能够解决问题。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-8 01:50:31 | 显示全部楼层
你的代码不对,data没有被定义
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-8 01:50:52 | 显示全部楼层
wrpython 发表于 2023-12-08 01:50
你的代码不对,data没有被定义

非常抱歉,我的回答有误。根据你提供的信息,问题在于 `data` 在代码中没有被定义。为了解决这个问题,你可以提前定义一个空列表 `data`,然后在遍历中不重新赋值,而是直接向 `data` 列表中添加子字典 `data.append(sjz)`。以下是修改后的代码示例:
data = []for tos in stk:    sym = tos.split('=')[0]    if sym not in jd:        jd.add(sym)        ks = now - now % 300        js = ks + 300        sjz = {'symbol': sym, 'price': pri, 'size': size, 'mmid': mmid, 'time': time1, 'now': now}        data.append(sjz)        print(sjz)        print(data)
在上面的代码中,我们提前定义了一个空列表 `data`,然后在遍历过程中,将每个子字典 `sjz` 直接添加到 `data` 中。这样就可以避免 `data` 被重置为空列表。

希望这个修改能够解决你的问题。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-8 02:00:39 | 显示全部楼层
还是不对,我需要为每一个sym都建立一个字典,字典为data = {sym:[],ks':ks,'js':js}

每次有新的sjz = {'symbol': sym, 'price': pri, 'size': size, 'mmid': mmid, 'time': time1, 'now': now}输入的时候
都需要存入相对应的data[sym]列表中
所以要设法让sjz的sym与data[sym]的sym保持一致

你还有其他方案吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-8 02:01:07 | 显示全部楼层
wrpython 发表于 2023-12-08 02:00
还是不对,我需要为每一个sym都建立一个字典,字典为d ...

非常抱歉给你带来了困惑。根据你的需求,既然每个 `sym` 都需要对应一个独立的字典,你可以使用一个字典来存储 `data`,其中每个键值对都表示一个 `sym` 对应的列表。以下是修改后的代码示例:data = {}  # 创建一个空字典for tos in stk:    sym = tos.split('=')    if sym not in jd:        jd.add(sym)        ks = now - now % 300        js = ks + 300        sjz = {'symbol': sym, 'price': pri, 'size': size, 'mmid': mmid, 'time': time1, 'now': now}        if sym not in data:            data[sym] = []  # 如果sym不在data字典中,创建一个空列表        data[sym].append(sjz)  # 将sjz添加到对应的sym的列表中        print(sjz)        print(data)在上面的代码中,我们使用 `data` 字典来存储每个 `sym` 对应的列表。在遍历过程中,首先检查 `sym` 是否已经在 `data` 字典中存在,如果不存在,则通过 `data[sym] = []` 创建一个空列表。然后,将 `sjz` 添加到 `data[sym]` 列表中。这样,每个 `sym` 对应的列表就可以独立地存储数据,从而解决了 `sjz` 的 `sym` 与 `data` 的 `sym` 不一致的问题。希望这个修改可以解决你的问题。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-7-8 11:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表