如何将字符串形式的嵌套数组转为Python的list类型?
解决Python字符串列表转嵌套List的问题
嘿,我来帮你搞定这个问题!你现在遇到的核心问题是把字符串形式的嵌套列表当成普通字符串处理了,导致numpy把它拆成了单个字符,最终tolist()后得到字符列表。下面一步步给你讲清楚怎么改:
问题根源
你当前的代码里,d2 = [d['array1_2']for d in data8]拿到的是字符串类型的列表(比如"[[0, 45], [0, -45, 45], ...]"),然后直接用np.array(a2)把这个字符串转成numpy数组时,numpy会把它当成字符数组——也就是把字符串里的每一个字符都作为数组的一个元素,再调用.tolist()自然就得到了单个字符组成的列表。
解决方案
在处理这些字段之前,先用ast.literal_eval()把字符串形式的列表解析成真正的Python嵌套列表。注意要判断字段是否是列表格式(避免像"ad"、"jytj"这类普通字符串报错)。
修改后的完整代码
import numpy as np import json import ast import itertools data1 = b'[{"id":"1","array1_1":"0","array1_2":"1","array2_1":"2","array2_2":"3","array3_1":"44","array3_2":"55"},{"id":"asd","array1_1":"234","array1_2":"[[0, 26, 60, 45], [0, -45, 45]]","array2_1":"[[23, 345], [543, 321]]","array2_2":"jytj","array3_1":"5","array3_2":"6"},{"id":"bb","array1_1":"bbb","array1_2":"ad","array2_1":"[[23, 345], [543, 321]]","array2_2":"[[0, 45], [45]]","array3_1":"[[34, 45], [66, 88]]","array3_2":"sfw"},{"id":"aa","array1_1":"aa","array1_2":"[[0, 26, 60, 45], [0, -45, 45]]","array2_1":"gfd","array2_2":"[[0, 45], [45]]","array3_1":"sdf","array3_2":"[[26, 60], [0], [56, 34, 45]]"},{"id":"ss","array1_1":"00","array1_2":"[[0, 45], [0, -45, 45], [0, -45, 45, -26]]","array2_1":"[[31, 233], [152, 151], [190, 204], [205, 87], [231, 48], [255, 194]]","array2_2":"[[0, 45], [45], [45], [26, 45, 63], [45], [0, 26, 45, 63]]","array3_1":"[[29, 194], [32, 234], [165, 229], [232, 46], [258, 190]]","array3_2":"[[45], [0, 45], [0, 26, 45], [0, -63, 45, 63], [0, 26, 45]]"}]' data2 = data1.decode() data3 = {"key" : [data2]} s = json.dumps(data3) data4 = str.encode(s) data5 = json.loads(data4) data6 = data5['key'] data7 = data6[0] data8 = ast.literal_eval(data7) # 新增:统一解析字符串形式的列表 def parse_list_str(s): try: # 只解析以[开头的字符串(判断是列表格式) if s.startswith('['): return ast.literal_eval(s) return s except: # 解析失败就返回原字符串 return s # 用parse_list_str处理所有可能包含列表的字段 d0 = [d['id']for d in data8] d1 = [parse_list_str(d['array1_1'])for d in data8] d2 = [parse_list_str(d['array1_2'])for d in data8] d3 = [parse_list_str(d['array2_1'])for d in data8] d4 = [parse_list_str(d['array2_2'])for d in data8] d5 = [parse_list_str(d['array3_1'])for d in data8] d6 = [parse_list_str(d['array3_2'])for d in data8] da = [d1,d2,d3,d4,d5,d6] for x in zip(*da): y = list(x) a1 = y[0] a2 = y[1] a3 = y[2] a4 = y[3] a5 = y[4] a6 = y[5] # 现在a2已经是嵌套列表了,直接赋值即可 c1 = a2 # 如果需要转numpy数组再转回列表也可以,结果一致 # b2 = np.array(a2) # c1 = b2.tolist() c2 = a4 c4 = a6 print(f"c1的类型:{type(c1)}") print(f"c1的内容:{c1}")
效果验证
运行修改后的代码,当处理id="ss"的条目时,c1会输出:
[[0, 45], [0, -45, 45], [0, -45, 45, -26]]
同时type(c1)的结果是<class 'list'>,完全符合你的需求。
补充说明
ast.literal_eval()是安全解析Python字面量的方法,比eval()更安全,不会执行恶意代码。- 我们写了
parse_list_str函数来统一处理字段:如果字符串以[开头,就尝试解析成列表;否则直接返回原字符串,避免普通字符串报错。
内容的提问来源于stack exchange,提问作者K.M. Lee
相关产品推荐
相关产品推荐

