使用特定的reduce()查找数字列表的模式

时间:2019-07-17 16:42:07

标签: python

请阅读:这是重复的问题。我在问如何专门使用reduce()解决此问题。

我需要创建一个将列表作为参数并返回模式的函数。它需要使用functools库中的reduce()函数来执行此操作。

我先尝试对数字进行排序,然后尝试解决此问题,但仍然不知道如何执行此操作。

from functools import reduce

#I believe the solution to this problem is something like this but it is missing something
def function(numbers)
    mode = reduce(lambda x,y: x if x == y else y, numbers)
    return mode

4 个答案:

答案 0 :(得分:2)

另一个版本:

from functools import reduce

numbers = [1, 1, 1, 3, 3, 3, 1, 3, 1, 1, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6]

def function(numbers):
    d = {}
    mode = reduce(lambda x, y: (lambda: [d.update([(x, d.get(x, 0)+1), ]), y])()[-1] if d.get(x, 0) < d.get(y, 0) else (lambda : [d.update([(y, d.get(y, 0)+1), ]), x])()[-1], numbers)
    return mode

print(function(numbers))

打印:

6

答案 1 :(得分:1)

您可以这样做

def get_mode(nums):
    return reduce(lambda x,y: x if nums.count(x) > nums.count(y) else y, nums)

答案 2 :(得分:1)

这是排序和迭代之后的一种方式:

import random
from bisect import bisect  # Binary search algorithm

# Input data
random.seed(0)
a = [random.randint(1, 20) for _ in range(10000)]

# Sort
def reduce_sort_fn(s, i):
    # Insert the element at a point where it will be sorted
    s.insert(bisect(s, i), i)
    return s
a_sorted = reduce(reduce_sort_fn, a, [])

# Compute mode by sorting and tracking current element count and max element count
def reduce_mode_fn(t, i):
    (current_count, current_elem), max_t = t
    current_t = (current_count + 1 if i == current_elem else 1, i)
    return current_t, max(current_t, max_t)
mode = reduce(reduce_mode_fn, a_sorted, ((0, 0), (0, 0)))[1][1]
print(mode)
# 11

# Check result with counter
from collections import Counter
mode_counter = Counter(a).most_common(1)[0][0]
print(mode_counter)
# 11

我认为时间复杂度为O(n ^ 2),因为即使使用二进制搜索在列表中插入也为O(n)...所以实际上等待O(n ^ 2 log(n))吗? (实际上,插入列表实际上是非常快的)内存将为O(n)。

如果您还可以使用字典,则可以这样计数:

def reduce_count_fn(d, i):
    # Insert the element at a point where it will be sorted
    d[i] = d.get(i, 0) + 1
    return d
d = reduce(reduce_count_fn, a, {})
m = reduce(lambda a, b: a if a[1] > b[1] else b, d.items())[0]

在时间和空间上将是O(n)。

答案 3 :(得分:0)

我对答案不满意,所以我认为我会仔细考虑问题,并帮助您开始做作业;)

首先,考虑reduce函数如何能够遍历迭代器并查看每对项目。

第二,考虑一下您需要如何计算有多少相同的事物。因此,在使用reduce之前,您需要对列表进行排序。

第三,考虑如何在函数之外跟踪所有这些东西。然后,您可以计算比较相似事物的次数,然后将其添加到外部列表中,然后使用该列表的最大值。

参考该程序:

from functools import reduce

mylist = [1,1,3,7,3,3,3,2,7,1,3]
mylist.sort()
print(mylist)

def myfunction(x,y):
    global mylist
    if x==y:
        print("yes")
    else:
        print("switch from " + str(x) + " to " + str(y))
    return y

reduce(myfunction,mylist)  

输出:

[1, 1, 1, 2, 3, 3, 3, 3, 3, 7, 7]
yes
yes
switch from 1 to 2
switch from 2 to 3
yes
yes
yes
yes
switch from 3 to 7
yes  

所以现在,考虑一下如果在程序顶部添加另一个全局变量(也许是“ mycount”)并在函数中引用它会发生什么情况。每次比较项目相同时,都设置全局mycount + = 1。然后,在比较失败后,取数字并将其添加到全局列表中。完成后,最大次数将是模式发生的次数。

但是,如果您想要该项目及其发生的次数,则需要使用字典数据结构。