Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping dict values based on keys in a list comprehension

Tags:

python

Lets say I have a dictionary where the keys are substring I want to use for a str search. I want to see if the keys exist in the elements of a list, and if they do, I'd like to set them equal to the value of that key and if there is no str match, set it equal to 'no match'.

d = {'jun':'Junior', 'jr':'Junior', 'sr':'Senior', 'sen':'Senior'}
phrases = ['the Jr. title', 'sr jumped across the bridge', 'the man on the moon']

This is what I've tried, however I just can't seem to fit in the 'no match' statement in the list comprehension. Help appreciated. PS. would like to stick with a dict/list comprehension method for my specific use case

# Tried
[[v for k,v in d.items() if k in str(y).lower()] for y in phrases]

# Output
[['Junior'],['Senior'],[]]

# Desired Output
[['Junior'],['Senior'],['no match']]
like image 953
chicagobeast12 Avatar asked Dec 01 '25 12:12

chicagobeast12


2 Answers

Just add an or ['no match'] to replace the empty list (which is falsey) with your ['no match'] placeholder in the outer list comprehension.

>>> d = {'jun':'Junior', 'jr':'Junior', 'sr':'Senior', 'sen':'Senior'}
>>> phrases = ['the Jr. title', 'sr jumped across the bridge', 'the man on the moon']
>>> [[v for k,v in d.items() if k in str(y).lower()] or ['no match'] for y in phrases]
[['Junior'], ['Senior'], ['no match']]
like image 190
Samwise Avatar answered Dec 03 '25 01:12

Samwise


What you have now is pretty close to what you're looking for. All your missing is the no-match condition. However, and my guess is that you tried this, you cannot put an else condition in a list comprehension that way. Fortunately, if you use generators, you can go over the list comprehension again to add in the else-condition as a separate if-condition:

[x if len(x) > 0 else ["no match"] for x in 
    map(lambda y: [v for k, v in d.items() if k in str(y).lower()], phrases)]

Everything inside the map does the exact same thing as what you have already; the map simply transforms this to a generator that can be iterated over. I then perform the other condition on the intermediate result. This code will produce the following output:

[['Junior'], ['Senior'], ['no match']]
like image 24
Woody1193 Avatar answered Dec 03 '25 01:12

Woody1193



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!