Python中的Map Reduce问题

3 投票
5 回答
4179 浏览
提问于 2025-04-17 03:08

我现在在做一个作业,遇到了一些困难。这个作业需要读取一个txt文件,然后计算里面有多少个回文和它们出现的频率。我需要用Map Reduce来实现这个功能。

比如说,字符串“bab bab bab cab cac dad”应该输出:

bab 3
cab 1
dad 1

这是我目前的进展

def palindrome(string):
    palindromes = []
    for word in string.split(" "):
        if (word == word[::-1]):
            palindromes.append(word)
    return palindromes 

string = "abc abd bab tab cab tat yay uaefdfdu"
print map(lambda x: palindrome(x), ["bab abc dab bab bab dad crap pap pap "])

现在打印的结果是

[['bab', 'bab', 'bab', 'dad', 'pap', 'pap', '']]

这是我在reduce部分的尝试

def p(lists):
for list in lists:

set_h = set(list) 

return set_h

我想用p函数创建一个包含所有找到的回文的集合。然后对这个列表中的回文进行计数,并把结果做成一个字典。

print reduce(p, [['bab', 'bab', 'bab', 'dad', 'pap', 'pap', '']])

我这样做对吗?

5 个回答

1

对于你的reduce函数,首先应该从一个空字典开始,然后更新或填充你的计数。reduce函数需要两个参数,一个可以是你的字典,另一个是你的回文字符串。你可以像这样在reduce中输入一个初始值:

reduce(lambda x, y: x+y, some_list, initial_value_for_x)

可以看看字典的get方法,了解如何设置默认值,这样可以帮助你大大简化你的reduce函数。

3

我觉得如果你的 map()reduce() 的输入是一个实际的单词列表,那会简单很多。为了做到这一点,你可以先用 .split() 方法把字符串分割成单词,然后再传给 map()。接着,map() 可以把每个单词处理成它自己(如果这个单词是回文的话),或者变成 None。之后,你可以用 filter() 来过滤掉那些 None 的结果,接着对剩下的结果进行排序,然后传给 reduce()。最后,reduce() 会把这些结果合并成一个 dict,这个字典会把单词和它们的总出现次数对应起来。

我不会给你一个完整的解决方案,因为我不想影响你的学习过程。

2

在你使用 map() 之前,先把字符串分割成一个列表。因为 map() 是用来处理列表、集合和字典的,而不是字符串。

word_list = words_str.split(" ")

除非作业要求你这样做,否则尽量不要使用 map-filter-reduceGVR 也这么说过。正确的做法是使用 Python 的 列表推导 语法。实际上,你可以用一个很简洁的单行代码来实现:

pal_count = {
    x: word_list.count(x)  # reduce-ish
    for x in word_list     # map-ish
    if x == x[::-1]        # filter-ish
    }
for x, y in pal_count.iteritems():
    print x, y             # print the results!

我们来分解一下这个过程...

  1. 先把结果放到一个字典对象里,以便后面打印:pal_count = {
  2. 定义返回的对象:x: word_list.count(x) 这里我们用键值对的方式,把回文字符串 x 和它出现的次数关联起来。count() 就像是一个内置的列表减少函数。
  3. 用一个 for 循环 遍历我们的列表,把当前值赋给 'x':for x in word_list
  4. 我们只想返回回文字符串,所以需要加一个比较操作符来 过滤 不合格的值:if x == x[::-1] # 这个逻辑很酷哦
  5. 太好了! }

顺便说一下,我之所以帮你做作业,是因为我从来没有做过我的作业。

相对来说,慢一些、灵活性差、可移植性差、也不那么 的做法是使用嵌套的 for 循环:

pal_count = dict()
for x in word_list:                     # same loop
    if x == x[::-1]                     # is this a palindrome?
        if x in pal_count:              # have we seen before?
            pal_count[x] += 1
        else:                           # this one is new!
            pal_count.setdefault(x, 1)

撰写回答