我想创建一个具有以下输出的json输出:
[ {'data': [<val1>,<valn>], 'name': '<nameA>'},
{'data': [<val1>,<valn>], 'name': '<nameB>'} ]
基本上,它采用由子列表组成的列表,并且对于每个子列表的第一个元素,值将附加到“name”,而余数将在属性“data”中形成单个列表。
下面的代码创建了所需的输出,但只有在项目列表中的每个子列表都有2个元素时才有效。
items= [['A', 30.0], ['B', 10.0], ['C', 9.28]]
print "ITEMS before==",items
items = [{"name":k, "data":[g]} for k,g in items]
print "ITEMS after==",items
正确的ouptut: [{'data':[30.0],'name':'A'},{'data':[10.0],'name':'B'},{'data':[9.28],'name': 'C'}]
问题是当子列表包含多于2个元素时,例如:
items= [['A', 1 ,30.0], ['B', 2, 10.0], ['C', 3, 9.28]]
应该产生:
[{'data': [1,30.0], 'name': 'A'}, {'data': [2,10.0], 'name': 'B'}, {'data': [3,9.28], 'name': 'C'}]
我尝试过类似的事情:
items = [{"name":k, "data":[ x[1:] for x in g] } for k,g in items]
但它会产生错误: ValueError:解压缩的值太多
我如何才能获得所需的输出?
答案 0 :(得分:6)
试试这个:
[{'name': x[0], 'data': x[1:]} for x in my_list]
如果你正在使用Python 2.7或3.x,你可以使用理解来创建一个dict和一个列表。 [1:]
切片会为您提供一个包含第一个元素的列表。
您的问题是,您通过在不需要的地方([x[1:] for x in g]
)写下理解来重复创建列表的工作。切片已经返回一个列表,如果g不是列表,这个(如你所见)将会失败。
由于x[1:]
会在双元素列表中调用,因此会返回单个元素列表,只要您的列表至少有两个长且第一个值始终为&#39; name& #39;键。观察:
>>> my_list = [['A', 1 ,30.0], ['B', 2, 10.0], ['C', 3, 9.28]]
>>> [{'name': x[0], 'data': x[1:]} for x in my_list]
[{'data': [1, 30.0], 'name': 'A'}, {'data': [2, 10.0], 'name': 'B'}, {'data': [3, 9.28], 'name': 'C'}]
>>> my_list = [['A', 1 ,30.0], ['B', 2, 10.0], ['C', 3]]
>>> [{'name': x[0], 'data': x[1:]} for x in my_list]
[{'data': [1, 30.0], 'name': 'A'}, {'data': [2, 10.0], 'name': 'B'}, {'data': [3], 'name': 'C'}]
答案 1 :(得分:5)
如果您知道第一项始终是关键,那么此列表理解将完成工作:
new_dict = [{"name":k[0], "data":k[1:]} for k in items]
你得到“解压太多值”的原因是因为你有比你有变量更多的值。 Python不知道将剩余的变量分配给g
。如果items
数组每个子数组总是有三个元素,那么您可以创建一个非常具体的理解:new_dict = [{"name":k, "data":[g,d]} for k,g,d in items]
。但到目前为止,第一次理解更具通用性。
答案 2 :(得分:1)
虽然其他人给出的方法适用于python 2.x和3.x,但如果你使用的是3.x(根据你的打印语句判断你不是),有一个更简单的方法使用您使用的语法相同的变体:
res = [{"name": k, "data": g} for k, *g in items]
这基本上说&#34;将第一个值放入k
,其余值放入g
。但是,这仅在python 3.x中可用。