0

Why is this returning an empty list:

def word_lengths(phrase):

    result = []
    map(lambda x: result.append(x) , phrase.split())
    return result

Where as this returns a list of the length of each word in the phrase:

def word_lengths(phrase):

    return list(map(lambda x: len(x) , phrase.split()))
4
  • Please provide an example input (phrase) and expected output vs real output. Commented Nov 29, 2017 at 0:19
  • Note that lambda x: len(x) is just a more complicated way of saying len, and that the whole thing would be more pythonically expressed as a list comprehension: [len(word) for word in phrase.split()]. Commented Nov 29, 2017 at 0:24
  • Possible duplicate of Python 3 map dictionary update method to a list of other dictionaries (it's about dict.update, not list.append, but everything else about it is the same) Commented Nov 29, 2017 at 1:12
  • For one, you're not assigning that map call to anything in the former case. And even calling list(map(... with the result.append(x) as your lambda will just return a list of None for as many elements as there are in phrase.split() Commented Nov 29, 2017 at 1:24

1 Answer 1

3

In Python 3, map results in a generator, which is lazily evaluated.

You need to iterate over it to take effect, for example by calling the list constructor on it:

result = []
list(map(lambda x: result.append(x) , phrase.split()))
return result

This mutates result as you had probably expected.

Note though, that the same can be achieved in a much simpler way:

return phrase.split()
Sign up to request clarification or add additional context in comments.

3 Comments

Returning phrase.split() directly is much more Pythonic. Abusing map for side-effects is profoundly misunderstanding the point of functional programming idioms. map (and list comprehensions and generator expressions) should always be side-effect free, to avoid lots of spooky action at a distance that makes it hard to reason about the code.
Also, side-note: For the extremely rare cases where using map for side-effects makes sense (usually using the multiprocessing map-like functions to parallelize a task), the best way to force it to run to completion is to wrap it in a collections.deque constructor with a maxlen of 0 (which is optimized to run iterators to exhaustion without storing a thing), e.g. collection.deque(map(...), 0) which would avoid making a potentially large temporary list of Nones for no purpose.
I appreciate the side effect comment, and that phrase.split() is a much easier way to do it. It was a project question on a python course to understand maps, and I just had an idea about whether or not you could update an external list within the lambda...purely academic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.