Reputation: 406
I want to turn a list of interspersed values into an array of dictionaries.
I'm trying to make a list of prediction values in Python capable to be used with a JSON API. Once I have the dictionary, I'll use json.dumps
on it.
my_list = [35, 2.75, 67, 3.45] # in form of: (value, score, value, score)
Ideal outcome:
my_array_of_dicts = [{'value':35, 'score':2.75}, {'value':67 'score':3.45}]
Here's what I've tried.
First attempt:
d = dict(zip(my_list[::2], my_list[1::2]))
And it produces...
> {35: 2.75,
67: 3.45}
I'm not sure how to get custom keys. Or have each pair as its own dictionary.
Second attempt:
[{'value':i, 'score':i} for i in my_list]]
> [{'value':35, 'score':35}, {'value':2.75, 'score':2.75},
{'value':67, 'score':67}, {'value':3.45, 'score':3.45}]
It's close but it doesn't account for every second value being a score.
Upvotes: 5
Views: 11304
Reputation: 219
class my_dictionary(dict):
# __init__ function
def __init__(self):
self = dict()
# Function to add key:value
def add(self, key, value):
self[key] = value
# Main Function
dict_obj = my_dictionary()
Then you can assign values saved in tmpkey
and tmpvalue
to key value pairs in dictionary with the following code.
dict_obj.key = tmpkey
dict_obj.value = tmpvalue
dict_obj.add(dict_obj.key, dict_obj.value)
And for creating a list of dictionary all you need is to create an empty list and assign copy of your dictionary in each element of the list.
dicMatrix = []
dictionary_copy = dict_obj.copy()
dicMatrix.append(dictionary_copy)
In this way your dictionary will grow dynamically and the reason behind making a copy of dictionary is that if you will change the values of the dictionary each time the new value will be added to the list, otherwise the reference to the dictionary will be assigned to the list.
Upvotes: 0
Reputation: 14216
One-liner using comprehension:
[{'value': k, 'score': v} for k, v in [my_list[i: i + 2] for i in range(0, len(my_list), 2)]]
[{'score': 2.75, 'value': 35}, {'score': 3.45, 'value': 67}]
Using your original attempt:
[{'value': k, 'score': v} for k,v in zip(my_list[::2], my_list[1::2])]
Another more verbose way
from operator import itemgetter
getters = [itemgetter(slice(i, i + 2)) for i in range(0, len(my_list), 2)]
vals = [g(my_list) for g in getters]
def score_vals(s):
k, v = s
return {'value': k, 'score': v}
list(map(score_vals, vals))
Upvotes: 2
Reputation: 16593
Try this:
my_list = [35, 2.75, 67, 3.45]
list_of_dicts = [{'value': k, 'score': v} for k, v in zip(iter(my_list), iter(my_list))]
print(list_of_dicts)
Output:
[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]
A little timing comparison between my solution and the solutions by others that use list slicing:
In [1]: my_list = [35, 2.75, 67, 3.45] * 100 # making it longer for better testing results
In [2]: def zip_with_slice():
...: return [{'value': v, 'score': s} for v, s in zip(my_list[::2], my_list[1::2])]
...:
In [3]: def zip_with_iter():
...: return [{'value': k, 'score': v} for k, v in zip(iter(my_list), iter(my_list))]
...:
In [4]: %timeit zip_with_slice()
56.5 µs ± 1.27 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [5]: %timeit zip_with_iter()
93 µs ± 2.99 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
As you can see, my solution using iterators is quite a bit (5-6x) faster than solutions using slicing.
Upvotes: 3
Reputation: 71580
Another way to do this, using dict
with arguments (**kwargs**
):
>>> my_list = [35, 2.75, 67, 3.45]
>>> [dict(value=x,score=y) for x,y in zip(my_list[::2], my_list[1::2])]
[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]
>>>
Upvotes: 2
Reputation: 691
Using List Comprehension:
>>> my_list = [35, 2.75, 67, 3.45]
>>> my_dict = [{'value': my_list[i], 'score': my_list[i+1]} for i in range(0, len(my_list), 2)]
>>> my_dict
[{'score': 2.75, 'value': 35}, {'score': 3.45, 'value': 67}]
Upvotes: 2
Reputation: 344
d = map(dict, map(lambda t:zip(('value','score'),t), zip(my_list[::2], my_list[1::2])))
print(list(d))
Upvotes: 3
Reputation: 92440
You're really close with the zip
version. You just need to make the object and specify the keys.
my_list = [35, 2.75, 67, 3.45]
[{'value': v, 'score': s} for v, s in zip(my_list[::2], my_list[1::2])]
result:
[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]
Upvotes: 6
Reputation: 186
In your second attempt, do score: i + 1. In the loop do for i in range(0, len(my_list), 2).
Upvotes: 3