Add an element in each dictionary of a list (list comprehension)
Question:
I have a list of dictionaries, and want to add a key for each element of this list.
I tried:
result = [ item.update({"elem":"value"}) for item in mylist ]
but the update method returns None, so my result list is full of None.
result = [ item["elem"]="value" for item in mylist ]
returns a syntax error.
Answers:
>>> a = [ { 1:1 }, {2:2}, {3:3} ]
>>> for item in a:
... item.update( { "test": "test" } )
...
>>> a
[{'test': 'test', 1: 1}, {'test': 'test', 2: 2}, {'test': 'test', 3: 3}]
You are using a list comprehension incorrectly, the call to item.update
returns a None
value and thus your newly created list will be full of None
values instead of your expected dict
values.
You need only to loop over the items in the list and update each accordingly, because the list holds references to the dict
values.
You don’t need to worry about constructing a new list of dictionaries, since the references to your updated dictionaries are the same as the references to your old dictionaries:
for item in mylist:
item.update( {"elem":"value"})
Either do not use a list comprehension, or return a new dict based on the original dict plus the new key:
[dict(list(item.items()) + [("elem", "value")]) for item in mylist]
If you want to use list comprehension, there’s a great answer here:
https://stackoverflow.com/a/3197365/4403872
In your case, it would be like this:
result = [dict(item, **{'elem':'value'}) for item in myList]
Eg.:
myList = [{'a': 'A'}, {'b': 'B'}, {'c': 'C', 'cc': 'CC'}]
Then use either
result = [dict(item, **{'elem':'value'}) for item in myList]
or
result = [dict(item, elem='value') for item in myList]
Finally,
>>> result
[{'a': 'A', 'elem': 'value'},
{'b': 'B', 'elem': 'value'},
{'c': 'C', 'cc': 'CC', 'elem': 'value'}]
You can use map.
result = map(lambda item: dict(item, elem='value'), myList)
If you already have the list of lements you can do:
#elements = ['value'] * len(myList)
result = map(lambda item: dict(item[0], elem=item[1]),zip(myList,elements))
then you have the results
@vk1011’s answer is good and can be extended with the spread operator concisely and new dictionary objects are an added benefit
-
To override any existing key’s value with the new one you can put the spread operator before the new item
result = [{**item, 'elem':'value'} for item in myList]
-
To override the new entry’s value with an existing one, use the spread operator after the new item
result = [{'elem':'value', **item} for item in myList]
Both methods will give a list of dictionary objects including the new item
traditionally but faster than the other (sophisticated) answers:
myList = [{'a': 'A'}, {'b': 'B'}, {'c': 'C', 'cc': 'CC'}]
for item in myList: item['elem']='value'
some timings:
%timeit result = [dict(item, **{'elem':'value'}) for item in myList]
865 ns ± 8.89 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit result = [dict(item, elem='value') for item in myList]
854 ns ± 5.37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit result = list(map(lambda item: dict(item, elem='value'), myList))
1.22 µs ± 86.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit for item in myList: item.update({'elem':'value'})
464 ns ± 3.72 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit for item in myList: item['elem']='value'
124 ns ± 0.31 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit [dict(list(item.items()) + [("elem", "value")]) for item in myList]
1.59 µs ± 14.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
I have a list of dictionaries, and want to add a key for each element of this list.
I tried:
result = [ item.update({"elem":"value"}) for item in mylist ]
but the update method returns None, so my result list is full of None.
result = [ item["elem"]="value" for item in mylist ]
returns a syntax error.
>>> a = [ { 1:1 }, {2:2}, {3:3} ]
>>> for item in a:
... item.update( { "test": "test" } )
...
>>> a
[{'test': 'test', 1: 1}, {'test': 'test', 2: 2}, {'test': 'test', 3: 3}]
You are using a list comprehension incorrectly, the call to item.update
returns a None
value and thus your newly created list will be full of None
values instead of your expected dict
values.
You need only to loop over the items in the list and update each accordingly, because the list holds references to the dict
values.
You don’t need to worry about constructing a new list of dictionaries, since the references to your updated dictionaries are the same as the references to your old dictionaries:
for item in mylist:
item.update( {"elem":"value"})
Either do not use a list comprehension, or return a new dict based on the original dict plus the new key:
[dict(list(item.items()) + [("elem", "value")]) for item in mylist]
If you want to use list comprehension, there’s a great answer here:
https://stackoverflow.com/a/3197365/4403872
In your case, it would be like this:
result = [dict(item, **{'elem':'value'}) for item in myList]
Eg.:
myList = [{'a': 'A'}, {'b': 'B'}, {'c': 'C', 'cc': 'CC'}]
Then use either
result = [dict(item, **{'elem':'value'}) for item in myList]
or
result = [dict(item, elem='value') for item in myList]
Finally,
>>> result
[{'a': 'A', 'elem': 'value'},
{'b': 'B', 'elem': 'value'},
{'c': 'C', 'cc': 'CC', 'elem': 'value'}]
You can use map.
result = map(lambda item: dict(item, elem='value'), myList)
If you already have the list of lements you can do:
#elements = ['value'] * len(myList)
result = map(lambda item: dict(item[0], elem=item[1]),zip(myList,elements))
then you have the results
@vk1011’s answer is good and can be extended with the spread operator concisely and new dictionary objects are an added benefit
-
To override any existing key’s value with the new one you can put the spread operator before the new item
result = [{**item, 'elem':'value'} for item in myList]
-
To override the new entry’s value with an existing one, use the spread operator after the new item
result = [{'elem':'value', **item} for item in myList]
Both methods will give a list of dictionary objects including the new item
traditionally but faster than the other (sophisticated) answers:
myList = [{'a': 'A'}, {'b': 'B'}, {'c': 'C', 'cc': 'CC'}]
for item in myList: item['elem']='value'
some timings:
%timeit result = [dict(item, **{'elem':'value'}) for item in myList]
865 ns ± 8.89 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit result = [dict(item, elem='value') for item in myList]
854 ns ± 5.37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit result = list(map(lambda item: dict(item, elem='value'), myList))
1.22 µs ± 86.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit for item in myList: item.update({'elem':'value'})
464 ns ± 3.72 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit for item in myList: item['elem']='value'
124 ns ± 0.31 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit [dict(list(item.items()) + [("elem", "value")]) for item in myList]
1.59 µs ± 14.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)