Issue
I'm experimenting around with the use of map
, filter
, and reduce
in Python 3.6 at the moment. What I'm trying to do is, given a list of dictionaries, change all the values associated with a certain key to a lower-case value. For example:
message_one = {"content": "I'm glad I know sign language, it's pretty handy."}
message_two = {"content": "I am on a seafood diet. Every time I see food, I eat it."}
message_three = {"content": "Labyrinths are amazing."}
messages = [message_one , message_two , message_three]
print(to_lowercase(tweets))
#to_lowercase should just return the a list of dictionaries, but content lower-cased.
I attempted to use map at first.
def to_lowercase(messages):
lower_case = map(lambda x: x["content"].lower(), messages)
return lower_case
However, this just seems to return a list of all the content-messages in a list and does not perserve the dictionary format.
I don't believe reduce
would be proper in this scenario because I'm not looking to return a single value at the end, and filter
does not seem to make sense either here.
How would I use either map
, reduce
, or filter
to achieve this job?
Solution
(Note, this answer assumes you are using Python 2; if you are using Python 3 take into account that map()
returns an iterator and you'd need to add a loop of some sort to see the results).
If you insist on using map()
, then you want to create a new function to apply to each existing dictionary:
def dict_lowercase_content(d):
"""Produces a copy of `d` with the `content` key lowercased"""
copy = dict(d)
if 'content' in copy:
copy['content'] = copy['content'].lower()
return copy
def to_lowercase(tweets):
return map(dict_lowercase_content, tweets)
The dict_lowercase_content()
makes no assumptions about what keys are present in the dictionary; it'll create a shallow copy of all the keys, and if a content
key is present it is lowercased.
Of course, if you can be certain that only the content
key is important and always present, you could just create entirely new dictionaries with just that key;
def to_lowercase(tweets):
return map(lambda d: {'content': d['content'].lower()}, tweets)
If updating dictionaries in-place is fine however (which would be more efficient), just use a loop:
def to_lowercase(tweets):
for tweet in tweets:
if 'content' in tweet:
tweet['content'] = tweet['content'].lower()
Note that this function returns None
! This is the Python convention; when altering mutable objects in-place, don't return those objects again as the caller already has a reference.
You can't use reduce()
or filter()
for this job.
filter()
selects elements from the iterable. You are not selecting, you are transforming.reduce()
aggregates elements; each element from the input is passed to a function together with a running result; whatever the function returns is taken as the updated result. Think summing, or concatenating, or traversing a tree. Again, you are not aggregating, you are transforming.
Answered By - Martijn Pieters
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.