Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Creating a dictionary using list comprehension from a list using lambda

Conceptually, here is what I want to do:

lookup = {'A': 'aaa', 'B': 'bbb', 'C': 'ccc'}
keys = ['A', 'B', 'Z'] # Note 'Z' does not exist in dict
result = {}
for key in keys:
    if key in lookup:
        result[key] = lookup[key]
    else:
        result[key] = None

The above code yields the following, i.e.

# result == {'A': 'aaa', 'Z': None, 'B': 'bbb'}

Based on the advise in this post about dictionary comprehension syntax I am able to do the following using v2.6 syntax:

result = dict((lambda x: (x, lookup[x]) if x in lookup else (x, None))(key) for key in keys)

Which works and produces same results.

However, I was hoping that I would be able to do the following in v2.7 style (also mentioned in the above post). But that does not seem to work,

result = { (lambda x: x: a_dict[x] if x in a_dict else x: None)(key) for key in a_list }

I seem to be running afoul of use of : in lambda with that in denoting a key. I have also reviewed the examples given in the original PEP, too. They don't provide any guidance, either. Below is the output from command line:

>>> result = { (lambda x: x : a_dict[x] if x in a_dict else x: None)(key) for key in a_list }
  File "<stdin>", line 1
    result = { (lambda x: x : a_dict[x] if x in a_dict else x: None)(key) for key in a_list }
                            ^
SyntaxError: invalid syntax

What am I doing wrong? Is it possible to do what I am trying to do, i.e. use v2.7 syntax of dictionary comprehension with lambda?

Please note that I ask this only out of curiosity; it's not that I have a compulsion to write such production code, one that would require an expert to understand!

PS: I should mention two other related posts that I found helpful while trying do this. First is about using lambda in list comprehension. And another is creating a dictionary using list.

like image 298
Alok Lal Avatar asked Dec 08 '22 01:12

Alok Lal


1 Answers

To do what you are trying with dictionary comprehension, you should make use of dict.get() method. Example -

>>> lookup = {'A': 'aaa', 'B': 'bbb', 'C': 'ccc'}
>>> keys = ['A', 'B', 'Z']
>>> result = {key:lookup.get(key) for key in keys}
>>> result
{'Z': None, 'A': 'aaa', 'B': 'bbb'}

dict.get() returns None if the key is not present in the dictionary. You can also specify a second argument to dict.get() which would be the default value returned, if the key you are trying to get is not present in the dictionary.


To answer the question, you cannot use lambda to return something like a key:value pair in a dictionary comprehension (since the : syntax is not valid). If you want to do that, you should use dict() function with a generator expression , Example -

result = dict((lambda x: (x,a_dict[x]) if x in a_dict else (x,None))(key) for key in a_list)

or the more readable map() version -

result = dict(map((lambda x: (x,a_dict[x]) if x in a_dict else (x,None)), a_list)
like image 97
Anand S Kumar Avatar answered Dec 14 '22 23:12

Anand S Kumar