2017-02-20 51 views
3

我正在Python 3.6中尝试使用mapfilterreduce。我想要做的是,给定一个字典列表,将与某个键关联的所有值更改为小写值。例如:如何使用映射到字典中的小写字符串?

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. 

我尝试使用地图在第一。

def to_lowercase(messages): 
    lower_case = map(lambda x: x["content"].lower(), messages) 
    return lower_case 

不过,这似乎只是一个列表中返回的所有内容消息的列表,并没有持之以恒的字典格式。 我不认为reduce在这种情况下是合适的,因为我不想在最后返回一个值,并且filter在这里似乎也没有意义。

我如何使用map,reducefilter来完成这项工作?

+0

不,'reduce()'和'filter()'在这里不是正确的工具。他们会做很不同的事情。 'filter()'用于*从列表中选择元素*,'reduce()'用于产生累加。就像一个总数或者一个列表或者任何其他需要中间结果用序列中的下一个元素进行更新的东西。这些不是你正在寻找的工具。 –

+0

字典中是否还有其他密钥需要保存?正在更新字典*是否可以接受,还是必须制作副本? –

+0

是否要更改现有字典中的值,或者是否要使用小写值返回* new *字典? – BrenBarn

回答

2

(注意,这个答案假定您使用Python 2,如果你正在使用Python 3考虑到map()返回迭代和你需要添加某种形式的循环看到的结果)。

如果你坚持要用map(),那么你要创建一个新的功能应用到每个现有词典:

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) 

dict_lowercase_content()是没有什么按键都出现在字典中的假设;它将创建一个所有密钥的浅副本,并且如果 a content密钥存在,则它是小写。当然,如果你可以确定只有content键是重要的并且总是存在,那么你可以用这个键创建全新的词典;

def to_lowercase(tweets): 
    return map(lambda d: {'content': d['content'].lower()}, tweets) 

如果更新词典就地是好的但是(这将是更高效的),只需使用一个循环:

def to_lowercase(tweets): 
    for tweet in tweets: 
     if 'content' in tweet: 
      tweet['content'] = tweet['content'].lower() 

请注意,该函数返回None!这是Python公约;当就地改变可变对象时,不要再返回那些对象,因为调用者已经有了一个引用。

您不能使用reduce()filter()执行此任务。

  • filter()选择来自可迭代元件。你没有选择,你正在改变。

  • reduce()聚合元件;来自输入的每个元素与运行结果一起被传递给一个函数;不管函数返回是作为更新后的结果。考虑总结,连接或遍历一棵树。再次,你不是聚合,你正在转变。

+0

我知道你知道:)但是......当你打印'to_lowercase()'的结果与OP一样时,除非你使用python 2或转换为'list',否则你会得到''。这就是为什么我不使用地图很多在链的末尾(好吧看到这个问题,OP显然是使用python 2) –

+0

@ Jean-FrançoisFabre:他们也正在寻找减少的事实是一个死的赠品.. –

+0

是的,我也看到了。幸运的是,现在'reduce'在'functools'中被“隐藏”了(隐藏起来),并且没有人想过使用它:使用'reduce'不会得到额外的分数! –

2

随着map

map(lambda x: {'content': x['content'].lower()}, messages) 

没有map

[{'content': x['content'].lower()} for x in messages] 

没有map,但更强大的:

[{y: x[y].lower()} for x in messages for y in x] 
3

简单溶胶ution获得的新类型的字典列表以及小写值:

dicts = [{k:v.lower() for k,v in d.items()} for d in messages] 
print(dicts) 

输出:

[{'content': "i'm glad i know sign language, it's pretty handy."}, {'content': 'i am on a seafood diet. every time i see food, i eat it.'}, {'content': 'labyrinths are amazing.'}] 
2

地图(),是把收集内置的高阶函数。我们提供一个匿名函数(lambda)来执行map,而不是将collection作为参数本身提供。一种达到目标的方法是:

transformed_messages = list(map(lambda x: {'content':x['content'].lower()}, messages))