wrpython 发表于 2023-12-7 20:34:04

字典嵌套列表,列表元素为字典,添加列表元素后报错

大家好,我有个问题想请教一下:

我写代码时设置了一组"字典-列表-字典"的嵌套结构,部分代码如下:

sym = tos.split('=')       #这部分是从一个日志文件里读取到的数据,这段代码的目的主要是把读取到的 字典sjz作为一个元素添加到一个空列表里,出现的问题是运行过程中报错,提示keyerror:


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

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



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



FishC 发表于 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# 将切割结果添加到字典中
    lst.append(sjz)# 将字典添加到列表中
    print(lst)
else:
    print("切割结果不正确")

在这个示例中,我们使用 `=` 进行字符串 `tos` 的切割,并将切割后的结果添加到字典 `sjz` 中。然后再将 `sjz` 添加到列表 `lst` 中。如果切割结果正确,那么最终输出的 `lst` 就是我们期望的结果。

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

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

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

wrpython 发表于 2023-12-7 20:37:05

发完帖子我忽然注意到一个问题,报错的时候,在提取5个INTZ.NQ后提示的是KeyError: 'HRTX.NQ',但是注释掉append语句后,同样的位置,5个INTZ.NQ后面的内容还是INTZ.NQ,而不是HRTX.NQ,会不会是因为我的文本文档数据有问题呢?我再去检查一下

FishC 发表于 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 小助理,如未能正确解答您的问题,请继续追问。

wrpython 发表于 2023-12-7 22:25:04

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

检查了一遍原始数据,文本数据的格式是正确的,在报错的那一行,文本格式没有问题。问题在别的地方

FishC 发表于 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# 将切割结果添加到字典中
      lst.append(sjz)# 将字典添加到列表中

print(lst)

2. 确保变量 `data` 包含正确的数据。请确保变量 `data` 包含正确的数据,并且每行数据都按照预期的格式进行分割。

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

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

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

wrpython 发表于 2023-12-7 23:00:24

我又重新试了一遍,我发现不使用print语句,程序也不会报错

FishC 发表于 2023-12-7 23:00:54

wrpython 发表于 2023-12-07 23:00
我又重新试了一遍,我发现不使用print语句,程序也不 ...

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

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

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

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

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

wrpython 发表于 2023-12-7 23:08:28

问题在代码中的data, 因为我用一个变量名替换掉data,程序就可以正常运行了,使用print语句也没有问题,但是如果直接用data,程序运行到某一个位置时就会报出keyerror的错误

FishC 发表于 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
            lst.append(sjz)
      else:
            print("切割结果不符合预期:", sym)
    except KeyError as e:
      print("发生了KeyError错误:", e)

print(lst)

在这个示例中,我们将主要的代码部分放入了一个 try 块中,并添加了一个 except 块来处理 `KeyError` 错误。当遇到 `KeyError` 错误时,打印出相关信息。

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

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

wrpython 发表于 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会被自动清空?而且看起来没有什么规律

FishC 发表于 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
            lst.append(sjz)
      else:
            print("切割结果不符合预期:", sym)
    except KeyError as e:
      print("发生了KeyError错误:", e)

print(lst)

在这个示例中,我们将 `lst` 的初始化移到了循环外部,确保每次循环都是从上一次结束的地方继续添加元素,而不是重新初始化。同时,在异常处理中打印出错误信息,以帮助调试报错的具体原因。

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

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

wrpython 发表于 2023-12-8 01:01:05

PYcharm怎么逐行运行查看运行结果

FishC 发表于 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 小助理,如未能正确解答您的问题,请继续追问。

wrpython 发表于 2023-12-8 01:38:42

我找到data会出错的原因了
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.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是’INTZ.NQ‘
所以会报错。

你有什么改进建议呢?

FishC 发表于 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 = {'ks': ks, 'js': js} # 使用sym作为键,创建data的子字典
      sjz = {
            'symbol': sym,
            'price': pri,
            'size': size,
            'mmid': mmid,
            'time': time1,
            'now': now
      }
      data['data'] = [] # 在data的子字典中创建一个空的列表
      data['data'].append(sjz) # 将sjz添加到对应的data子列表中
      print(sjz)
      print(data['data'])

在上面的代码中,我们使用 `sym` 作为键,将 `data` 的值设置为一个子字典。然后,在子字典中创建一个空的列表 `data['data']`,并将 `sjz` 添加到该列表中。这样,每个 `sym` 都有自己独立的子字典和对应的列表,避免了不同 `sym` 之间的冲突。

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

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

wrpython 发表于 2023-12-8 01:50:31

你的代码不对,data没有被定义

FishC 发表于 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('=')
    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 小助理,如未能正确解答您的问题,请继续追问。

wrpython 发表于 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列表中
所以要设法让sjz的sym与data的sym保持一致

你还有其他方案吗?

FishC 发表于 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不在data字典中,创建一个空列表      data.append(sjz)# 将sjz添加到对应的sym的列表中      print(sjz)      print(data)在上面的代码中,我们使用 `data` 字典来存储每个 `sym` 对应的列表。在遍历过程中,首先检查 `sym` 是否已经在 `data` 字典中存在,如果不存在,则通过 `data = []` 创建一个空列表。然后,将 `sjz` 添加到 `data` 列表中。这样,每个 `sym` 对应的列表就可以独立地存储数据,从而解决了 `sjz` 的 `sym` 与 `data` 的 `sym` 不一致的问题。希望这个修改可以解决你的问题。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1] 2 3 4 5 6 7 8
查看完整版本: 字典嵌套列表,列表元素为字典,添加列表元素后报错