简体   繁体   中英

Python dictionary comprehension to contain list of items not found in another dictionary

There is a list and a dictionary. If an item in the list is not present in the dictionary add the item to a new dictionary. Below is the for loop which I'm trying to convert to dictionary comprehension.

for i in range(1, len(list_a)):
    if dict_main.get(list_a,'') == '':
        dict_new[list_a[i]] = None

Dictionary comprehension method as follows

dict_new = {list_a[i] if dict_main.get(list_a[i], '') == '' else None: None for i in range(1, len(list_a))}

Comprehension works fine but it adds an extra (None, None) key value pair. If else is removed it throws 'else expected' error. Please guide me.

You have several issues in the code of your regular loop:

  • list indices start at 0 , hence you should write for i in range(0, len(list_a)) or you will miss the first element of the list.
  • a probable typo: dict_main.get(list_a,'') should be dict_main.get(list_a[i],'') .
  • what happens if you have a mapping x: '' in the dict? dict_main.get(x, '') returns '' and the mapping x: None is added to dict_new . Use x not in d to check if the key x is not mapped to a value in d .
  • not really an issue, but in Python you can write for x in my_list to iterate over the elements of a list if you don't need the index (if you need the index, enumerate is useful).

The rule of thumb is: first, fix the regular loop and then create a list/dict comprehension. Here's the fixed regular loop:

for x list_a:
    if x not in dict_main:
        dict_new[x] = None

Hence the dict comprehension (given in comment by @Kenny Ostrom):

dict_new = {x: None for x in list_a if x not in dict_main}

If you really need to produce a dict whose values are None , you can use dict.fromkeys with a collection of keys:

dict_new = dict.fromkeys(x for x in list_a if x not in dict_main)

Or, maybe clearer:

dict_new = dict.fromkeys(set(list_a) - set(dict_main))

Your dict comprehension trial is not filtered (no if at the end). It creates len(list_a) keys in the target dictionary, all mapped to None . Those keys are the elements of the list if dict_main.get(list_a[i], '') == '' (element not in dict_main or mapped to '' ), else None .

If several elements of the list are keys of the dict_main , the mapping None: None is added once then overriden because the keys of a dictionary are unique. This is why you have one (and only one) extra None: None at the end of the dictionary as soon as you have at least one element in the list that is a key of dict_main .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM