简体   繁体   English

如何在字典中使用map来小写字符串?

[英]How to use map to lowercase strings in a dictionary?

I'm experimenting around with the use of map , filter , and reduce in Python 3.6 at the moment. 我正在尝试使用Python 3.6中的mapfilterreduce 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. 我不认为在这种情况下reduce是正确的,因为我不打算在最后返回单个值,并且filter在这里似乎没有意义。

How would I use either map , reduce , or filter to achieve this job? 我如何使用mapreducefilter来完成这项工作?

Simple solution to get a list of new dicts with lowercased values: 简单的解决方案,使与小写值新类型的字典列表:

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

The output: 输出:

[{'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.'}]

(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). (注意,这个答案假设您正在使用Python 2;如果您使用的是Python 3,请考虑map()返回一个迭代器 ,您需要添加某种循环来查看结果)。

If you insist on using map() , then you want to create a new function to apply to each existing dictionary: 如果你坚持使用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)

The dict_lowercase_content() makes no assumptions about what keys are present in the dictionary; dict_lowercase_content()不假设字典中存在哪些键; it'll create a shallow copy of all the keys, and if a content key is present it is lowercased. 它将创建所有键的浅表副本, 如果存在content键,则它是小写的。

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; 当然,如果你可以确定只有content键是重要的并且始终存在,你可以用这个键创建全新的词典;

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 ! 请注意,此函数返回None This is the Python convention; 这是Python惯例; 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. 您不能对此作业使用reduce()filter()

  • filter() selects elements from the iterable . filter() 从iterable中选择元素 You are not selecting, you are transforming. 你没有选择,你正在改变。

  • reduce() aggregates elements ; reduce() 聚合元素 ; 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. 同样,你没有聚合,你正在改变。

With map : map

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

Without map : 没有map

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

Without map , but more robust: 没有map ,但更健壮:

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

map() is a built-in higher order function that transform a collection. map()是一个内置的高阶函数,用于转换集合。 We are supplying an anonymous function(lambda) for map to execute instead of providing the collection as an argument itself. 我们提供一个匿名函数(lambda)来执行map,而不是将集合作为参数本身提供。 One way to achieve what you want would be: 实现目标的一种方法是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM