遍历全局变量生成映射列表时出现类型矛盾报错,请求排查
这种一会儿说变量是int、一会儿又说它是list的bug真的太搞心态了😂,我来帮你捋捋问题出在哪!
核心问题:你漏看了某个「伪装」在后面的非int变量
从你提供的信息来看,你打印的变量确实都是int类型,但报错信息不会骗人——肯定有某个变量的值是列表,只是它没出现在你展示的print输出里(毕竟你用了# etc...,说明后面还有没列出来的变量)。
当循环遍历到这个列表类型的变量时,就会触发list indices must be integers or slices, not list错误;但你之前的print可能只输出了前面几个变量,没打到这个搞事的家伙,所以才会出现「我看的都是int,但代码说有list」的矛盾。
第一步:先找到那个搞事的变量
你可以在循环里加个过滤和排查逻辑,把所有非int类型的变量揪出来:
MEM_strings = [False] * 71 for var_name, var_value in list(globals().items())[29:]: # 先检查变量类型,把非int的都打印出来 if not isinstance(var_value, int): print(f"⚠️ 发现异常变量:{var_name} = {var_value},类型是 {type(var_value)}") continue # 再检查索引是否在合法范围内,避免越界报错 if 0 <= var_value < len(MEM_strings): MEM_strings[var_value] = var_name else: print(f"⚠️ 变量{var_name}的值{var_value}超出列表索引范围(0-70)")
运行这段代码,你就能看到那个导致报错的「列表类型变量」了——它就是矛盾的根源。
第二步:改用更稳定的变量筛选方式
你用list(globals().items())[29:]这种切片来选取变量的方式非常不稳定:虽然Python 3.7+的字典是有序的,但globals()的顺序会受变量定义顺序、导入操作、甚至解释器优化的影响,哪天你新增/删除了一个全局变量,这个切片的范围就全错了。
更靠谱的方式是通过变量名前缀来筛选(比如你所有目标变量都以MEM_开头),这样能精准定位到你要的变量,还不会混入其他无关的全局变量:
MEM_strings = [False] * 71 # 只处理以MEM_开头的整数类型全局变量 for var_name, var_value in globals().items(): if var_name.startswith("MEM_") and isinstance(var_value, int): if 0 <= var_value < len(MEM_strings): MEM_strings[var_value] = var_name else: print(f"⚠️ 变量{var_name}的值{var_value}不在列表索引范围内(0-70)")
这种方式既稳定,又能从根源上避免混入非目标类型的变量。
为什么会出现「矛盾」的报错?
你之前尝试var_value[0]时,报错说'int' object is not subscriptable,是因为当时循环到的还是int类型的变量;而之前的「list indices must be integers」错误,是循环到后面那个列表类型的变量时触发的——两次报错对应的是循环里的不同变量,所以才会看起来矛盾。
备注:内容来源于stack exchange,提问作者ealexandera

