【问题标题】:How to get all the maximums max function如何获得所有最大值max函数
【发布时间】:2021-10-17 00:05:24
【问题描述】:
data = ['str', 'frt']
max(data, key=len)

max 函数只返回一个字符串。

如何让它返回两个字符串?

两个字符串的长度相等,所以max 应该返回两个字符串,但它只返回一个,所以有没有办法返回所有最大项?

【问题讨论】:

标签: python max


【解决方案1】:

你可以把它写成列表推导式:

data = ['str', 'frt']
maxlen = max(map(len, data))
result = [s for s in data if len(s) == maxlen]

【讨论】:

  • 注意:maxlen 在列表理解之外计算是至关重要的(因此只调用一次)。
  • 另外,在第二行中使用max(a, key=len),而不是 max.map。
  • @AndyHayden 在这种情况下,maxlen 将是实际字符串,而不是 3,因此您必须再次调用 len 才能获得长度。在这里做这个似乎更合适。
【解决方案2】:

这是一个简单的函数,可以一次性完成:

def maxes(a, key=None):
    if key is None:
        key = lambda x: x
    m, max_list = key(a[0]), []
    for s in a:
        k = key(s)
        if k > m:
            m, max_list = k, [s]
        elif k == m:
            max_list.append(s)
    return m, max_list

在行动:

In [11]: maxes(['a', 'ab', 'a', 'cd'], key=len)
Out[11]: (2, ['ab', 'cd'])

这可能比运行其他海报提到的列表理解更快,也可能不会更快,当然也比排序更快......但一些测试表明它更快:

字符串示例:

In [20]: a = [''.join(random.choice('abc') for _ in xrange(random.randint(1, 100)))
                                           for i in xrange(1000)]

In [21]: %timeit maxes(a, key=len)
10000 loops, best of 3: 53 µs per loop

In [22]: %timeit m = max(map(len, a)); [s for s in a if len(s) < m]
10000 loops, best of 3: 104 µs per loop

In [23]: %timeit sorted_a = sorted(a, key=len, reverse=True); [s for s in a if len(s) == len(sorted_a[0])]
1000 loops, best of 3: 322 µs per loop

如果我们用键来查看整数:

In [30]: a = [random.randint(1, 10000) for i in xrange(1000)]

In [31]: %timeit maxes(a, key= lambda x: x**2)
10000 loops, best of 3: 150 µs per loop

In [32]: %timeit m = max(a, key=lambda x: x**2); [s for s in a if s**2 < m]
1000 loops, best of 3: 183 µs per loop

In [33]: %timeit sorted_a = sorted(a, key=lambda x: x**2, reverse=True); [s for s in a if s ** 2 == sorted_a[0] ** 2]
1000 loops, best of 3: 441 µs per loop

但是,如果没有键,列表理解会更好:

In [34]: %timeit maxes(a)
10000 loops, best of 3: 98.1 µs per loop

In [35]: %timeit m = max(a); [s for s in a if s < m]
10000 loops, best of 3: 49.2 µs per loop

In [36]: %timeit sorted_a = sorted(a, reverse=True); [s for s in a if s == sorted_a[0]]
10000 loops, best of 3: 152 µs per loop

这是意料之中的,因为冗余的键代码仍在应用中,如果我们要删除该逻辑(仅用 x 替换对 key(x) 的调用),该函数再次稍微更快: p>

In [37]: %timeit maxes2(a)
10000 loops, best of 3: 39.7 µs per loop

【讨论】:

  • 您的基准测试有误。对于 max+listcomp 解决方案,您总是使用 &lt; 而不是 ==,这使得 listcomp 的工作超出了应有的范围。
【解决方案3】:

根据定义,max 函数返回最大值。它不返回项目,只返回唯一的值(即使有多个项目具有相同的最大值)。 我建议您使用排序算法并获取所需的任何值。

在你的例子中:

data = ['str','frt']
sorted(data,key=len, reverse=True)
result = [s for s in data if len(s)==len(data[0])]

【讨论】:

  • 排序会比我认为的最大时间花费更多时间
  • 不多。就复杂性而言,排序是伪线性的,其中 max 是线性的,或多或少是等价的。排序后,您可以对数据执行许多很酷的操作,例如查找第二个最大值、最小值、二分搜索……当然这取决于您的需求。
  • 我添加了一些 timeit 信息,正如上面所建议的,对于大型数据集,排序明显变慢。我不明白在这里使用 max 可以实现什么排序......您似乎将它用作效率较低的 max,所以 -1。
  • 如果您不将结果分配给值,则调用 sorted 不会执行任何操作。你的意思是使用sort()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多