如何过滤一组 (int, str) 元组,以仅返回第一个元素中具有最小值的元组?

2023-12-06

假设我有一组表示带有“分数”的 URL 的元组:

{(0.75, 'http://www.foo.com'), (0.33, 'http://www.bar.com'), (0.5, 'http://www.foo.com'), (0.66, 'http://www.bar.com')}.

有什么简洁的方法可以过滤掉重复的 URL,只返回分数最低的 URL?也就是说,从上面的示例集中,我想得到以下集合,其中每个 URL 只出现一次,并且原始集合中对应的分数最低:

{(0.5, 'http://www.foo.com'),(0.33, 'http://www.bar.com')}

我想出了以下解决方案:

from collections import defaultdict

seen = defaultdict(lambda:1)
for score, url in s:
    if score < seen[url]:
        seen[url] = score

filtered = {(v,k) for k,v in seen.items()}

...但我觉得可能有一些更简单、更有效的方法来做到这一点,而不使用中间字典来跟踪最大元素,然后从中重新生成集合。通过第一个元素的最小值/最大值过滤一组元组的最佳方法是什么?


您已经实现了我能想到的最简单的方法。我要做的唯一改变是循环——一个稍微更简洁的版本是使用min.

seen = defaultdict(lambda: 1)  # `lambda: float('inf')` if scores can be > 1
for score, url in s:
    seen[url] = min(seen[url], score)

{(v,k) for k,v in seen.items()}
# {(0.33, 'http://www.bar.com'), (0.5, 'http://www.foo.com')}

如果你真的想要一个更短的解决方案,就像我说的那样,这不是最简单的方法,但它是一个简单的方法。大多数挑战是交换 URL 和分数,以便您可以在删除重复项时使用 URL 作为键。不言而喻,排序是这里的先决条件(这就是为什么我不像上面的解决方案那样喜欢这个解决方案)。

{(v, k) for k, v in dict(sorted(((v, k) for k, v in s), reverse=True)).items()}
# {(0.33, 'http://www.bar.com'), (0.5, 'http://www.foo.com')}

这个解决方案会变得更短,如果s看起来像这样:

s2 = {(v,k) for k, v in s}
s2 
# {('http://www.bar.com', 0.33), ('http://www.bar.com', 0.66), ...}

你只需要这样做

list(dict(sorted(s2, reverse=True)).items())
# [('http://www.foo.com', 0.5), ('http://www.bar.com', 0.33)]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何过滤一组 (int, str) 元组,以仅返回第一个元素中具有最小值的元组? 的相关文章

随机推荐