Reputation: 2390
I want to create a json output that has the following output:
[ {'data': [<val1>,<valn>], 'name': '<nameA>'},
{'data': [<val1>,<valn>], 'name': '<nameB>'} ]
Basically, it takes a list formed with sub-lists and for the first elements of each sub-list, the value goes to atttribute 'name' and the remain will form a single list in the attribute 'data'.
The code below create the desired output, however only works if each sublist on items list has 2 elements.
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
correct ouptut: [{'data': [30.0], 'name': 'A'}, {'data': [10.0], 'name': 'B'}, {'data': [9.28], 'name': 'C'}]
The problem is when the the sub-list have more than 2 elements, like:
items= [['A', 1 ,30.0], ['B', 2, 10.0], ['C', 3, 9.28]]
should produce:
[{'data': [1,30.0], 'name': 'A'}, {'data': [2,10.0], 'name': 'B'}, {'data': [3,9.28], 'name': 'C'}]
I've tried something like:
items = [{"name":k, "data":[ x[1:] for x in g] } for k,g in items]
but it produces an error: ValueError: too many values to unpack
How can i acco9mplish the desired output?
Upvotes: 1
Views: 2464
Reputation: 10298
Although the approach given by others works for python 2.x and 3.x, if you are using 3.x (which judging by your print statements you aren't), there is an even simpler approach using a variant of the same syntax you were using:
res = [{"name": k, "data": g} for k, *g in items]
This basically says "put the first value into k
, and the rest into g
. However, again, this is only available in python 3.x.
Upvotes: 1
Reputation: 1313
If you know that the first item will always be the key, then this list comprehension would get the job done:
new_dict = [{"name":k[0], "data":k[1:]} for k in items]
The reason that you're getting the "too many values to unpack" is because you have more values than you had variables. Python doesn't know to assign the remaining variables to g
. If the items
array always had three elements per sub-array, you could create a very specific comprehension like so: new_dict = [{"name":k, "data":[g,d]} for k,g,d in items]
. But the first comprehension is more versatile by far.
Upvotes: 5
Reputation: 18457
Try this:
[{'name': x[0], 'data': x[1:]} for x in my_list]
If you're using Python 2.7 or 3.x, you can use comprehensions to create a dict as well as a list. The [1:]
slice gives you a list with the first element onwards.
Your issue is that you're duplicating your effort to create a list, by writing a comprehension where you don't need one ([x[1:] for x in g]
). The slice already returns a list, and this (as you've seen) will fail if g is not a list.
Since x[1:]
will return a single-element list if called on a two-element list, this will work as long as your lists are at least two long and the first value is always the 'name' key. Observe:
>>> 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'}]
Upvotes: 6