Create an array of dictionaries from a Python list

Viewed 10548

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.

8 Answers

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}]

In your second attempt, do score: i + 1. In the loop do for i in range(0, len(my_list), 2).

d = map(dict, map(lambda t:zip(('value','score'),t), zip(my_list[::2], my_list[1::2])))
print(list(d))

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.

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))

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}]

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}]
>>> 
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.

Related