4

I have a list of dictionaries like so:

l = [{"integer":"1"},{"integer":"2"},{"integer":"3"},{"integer":"4"}]

I would like to do something similar to the following so that each of the numbers which are the value pair for the "integer" key are returned as integers:

l = [{"integer":"1"},{"integer":"2"},{"integer":"3"},{"integer":"4"}]
r = map(lambda x: x["integer"]=int(x["integer"]), l)
print r 
#[{"integer":1},{"integer":2},{"integer":3},{"integer":4}]

But this causes an error:

SyntaxError: lambda cannot contain assignment

Does anyone know of a clean way to do this in python? Preferably a oneliner using map or something similar?

pault
  • 41,343
  • 15
  • 107
  • 149
Justin Gardner
  • 605
  • 2
  • 9
  • 17

7 Answers7

3

Use a list comprehension comprehension

You will iterate through the dictionaries in the list and have them returned as x, then insert a new dictionary with your desired key and the integer value of the return within a new list

r = [{'integer': int(x['integer'])} for x in l]
Nick Dima
  • 348
  • 1
  • 10
3

You should just use a loop:

l = [{"integer":"1"},{"integer":"2"},{"integer":"3"},{"integer":"4"}]
for d in l:
    d["integer"] = int(d["integer"])
print(l)
#[{'integer': 1}, {'integer': 2}, {'integer': 3}, {'integer': 4}]

However, here is a one-liner that should work for you:

l = [{"integer":"1"},{"integer":"2"},{"integer":"3"},{"integer":"4"}]
[d.update({"integer": int(d["integer"])}) for d in l]
print(l)
#[{'integer': 1}, {'integer': 2}, {'integer': 3}, {'integer': 4}]

Be aware that dict.update() returns None, so if you assigned the output of the list comprehension to a variable it would be a list containing all Nones.

print([d.update({"integer": int(d["integer"])}) for d in l])
#[None, None, None, None]
pault
  • 41,343
  • 15
  • 107
  • 149
1

The following works in one line:

r = [{'integer':int(x['integer'])} for x in l]
print(r)
# [{'integer': 1}, {'integer': 2}, {'integer': 3}, {'integer': 4}]

This utilizes a dict comprehension inside a list comprehension.

Joel
  • 1,564
  • 7
  • 12
  • 20
  • Do you know of a way to do that without having to redefine the whole dictionary? – Justin Gardner Sep 11 '18 at 18:33
  • You could just say `l = [{'integer':int(x['integer'])} for x in l]` followed by `print(l)`. I just followed your code where you defined a new variable `r`, but you don't necessarily need to do this. – Joel Sep 11 '18 at 18:35
  • @Joel His code assigns a new variable, but it also modifies the original dictionaries in place (or would, if it were legal). It seems that the in-place modification is what he's really looking for. – Barmar Sep 11 '18 at 18:40
1
[i.update({w:int(k)}) for i in l for w,k in i.items()]

it the second loop is only looping over one key set, so take the two loops with gram of salt :)

Jonas Wolff
  • 2,034
  • 1
  • 12
  • 17
0

Awesome solution by one of my friends in a chat:

>>> listOfDict = [{1:1338}, {1:1338}, {1:1338}]
>>> y = 1337
>>> value = 1
>>> map(lambda x: x.update({value: y}), listOfDict)
[None, None, None]
>>> listOfDict
[{1: 1337}, {1: 1337}, {1: 1337}]
Justin Gardner
  • 605
  • 2
  • 9
  • 17
  • 1
    This is essentially equivalent to [my answer](https://stackoverflow.com/a/52282310/5858851), except you replaced the list comp with a call to `map`. BTW, this won't work in python3. In any case, I still say that you should just use a loop. – pault Sep 11 '18 at 20:10
0

You can try the following

l = [{"integer":"1"},{"integer":"2"},{"integer":"3"},{"integer":"4"}]
a = [dict(d, **{'abcd':5}) for d in l]
print(a)
[{'integer': '1', 'abcd': 4}, {'integer': '2', 'abcd': 4}, {'integer': '3', 'abcd': 4}, {'integer': '4', 'abcd': 4}]
Hoàng Lê
  • 141
  • 1
  • 1
0

Use **kwargs to copy keyword arguments from the existing dicts, then overwrite the ones you want like so:

[{**element, 'value_to_overwrite':'new value'} for element in list_of_dicts]
Michael Seltenreich
  • 3,013
  • 2
  • 29
  • 55