HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

List Comprehension in Pythonic answer to LPTHW ex48

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
comprehensionpythonicanswerlpthwex48list

Problem

I'm not really seeing any use for a generator here, unless there's some way to hook a generator into a language dictionary.

But in the following code, the longhand version of the if statement (type_check()) returns a tuple (foo, bar) but to get the tuple from (my first ever) lc (type_identify) it needs to be called from result[0], as opposed to simply result.

Is this normal or am I doing something wrong in the lc?

word_types = {'noun': ['bear', 'princess', 'door'], 
            'verb': ['go', 'run', 'hide', 'stop', 'close', 'kill', 'eat'], 
            'stop': ['in', 'of', 'at', 'to', 'from', 'the'], 
            'direction': ['up', 'down', 'north', 'south', 
                        'east', 'west', 'back', 'forward']}

def type_check(word):
    word = word.lower()
    for label, type in word_types.items():
            if word in type:
                return (label, word)

def type_identify(word):
    word = word.lower()
    return [ (label, word) for label, type in word_types.items() if word in type ]

def scan(sentence):
    sentence_list = sentence.split()
    for k, v in enumerate(sentence_list):
        if type_identify(v):
            sentence_list[k] = type_identify(v)[0] #needed to add [0]
        else:
            try:
                sentence_list[k] = ('number', int(v))
            except ValueError:
                sentence_list[k] = ('error', v)
    return sentence_list

Solution

That's normal, because with the list comprehension you're generating a whole
list of results instead of returning the first time the check succeeds.

If you want to have the equivalent code to the loop version, that is, just
compute the first value or return None if no check succeeds, you can use a
generator as follows:

return next(((label, word)
             for label, type in word_types.items()
             if word in type),
            None)


where the generator is exactly as the list comprehension, but with parentheses
instead of square brackets and next is a built-in method to get the next value
from an iterator or return the default value if the iterator is exhausted.

Note: if you don't pass a default value you'll get a StopIteration when the iterator is exhausted.

Code Snippets

return next(((label, word)
             for label, type in word_types.items()
             if word in type),
            None)

Context

StackExchange Code Review Q#58036, answer score: 3

Revisions (0)

No revisions yet.