在列表列表中查找最常见的元素
Finding the most common element in a list of lists
我得到了这样一个列表列表:
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
并且期望的输出是:{(2,2)}
.
我需要找到出现频率最高的元素。如果有元素重复同样多次,它必须 return 多个值。
我尝试用三个列表的交集来解决它,但它打印出 {(2,1), (2,2)}
,而不是 {(2,2)}
,因为元素 (2,2)
在第一个列表中重复了两次.
我看到了一些 import collections
的示例,但我不理解它们,所以我不知道如何更改代码以适合我的问题。
我还尝试了以下方法:
seen = set()
repeated = set()
for l in pairs:
for i in set(l):
if i in seen:
repeated.add(i)
if i in repeated:
repeated.add(i)
else:
seen.add(i)
但仍然没有return正确答案。
collections.Counter()
会起作用...您只需要弄清楚如何传递嵌套列表中的所有对,您可以通过列表理解来做到这一点。例如:
from collections import Counter
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
counts = Counter(pair for l in pairs for pair in l)
counts.most_common(1)
# [((2, 2), 4)]
如果出现平局,您将需要查看排名靠前的选项并挑出数量相同的选项。您可以通过查看 counts.most_common()
.
获得排序列表
itertools.groupby
是处理这种情况的常用方法。例如,如果您有平局,您可以获得所有排名靠前的条目,例如:
from collections import Counter
from itertools import groupby
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1), (3, 2)]]
counts = Counter(pair for l in pairs for pair in l)
count, groups = next(groupby(counts.most_common(), key=lambda t: t[1]))
[g[0] for g in groups]
# [(2, 2), (3, 2)]
不使用 collections
中的 Counter
方法的替代解决方案:
def get_freq_tuple(data):
counts = {}
for pairs in data:
for pair in pairs:
counts[pair] = counts.get(pair, 0) + 1
return [pair for pair in counts if counts[pair] == max(counts.values())]
if __name__ == "__main__":
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1),
(3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
print(get_freq_tuple(pairs))
输出:
[(2, 2)]
解释:
- 计算每个元组的出现次数并将它们存储在字典中。字典的键是元组,值是出现。
- 根据元组的最大出现次数过滤字典中的元组。
免责声明:
- 使用
collections
中的 Counter
方法效率更高。
参考文献:
正如评论中所暗示的那样,defaultdict
非常有帮助。
from collections import defaultdict
我们有“成对”,但由于您想要 所有 列表中出现频率最高的,我们会将其展平。
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
flat_pairs = [tpl for lst in pairs for tpl in lst]
现在我们将创建一个默认为零的 defaultdict
来保存我们的计数,并迭代 flat_pairs 以将计数添加到字典中。
counts = defaultdict(lambda: 0)
for tpl in flat_pairs:
counts[tpl] += 1
或者我们可以跳过展平阶段:
counts = defaultdict(lambda: 0)
for lst in pairs:
for tpl in lst:
counts[tpl] += 1
我们可以通过对字典的值使用 max
来找到最大计数值,然后使用列表理解来获得具有最大计数的一个或多个元组。
max_count = max(counts.values())
max_count_tuples = [tpl for tpl, count in counts.items() if count == max_count]
我得到了这样一个列表列表:
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
并且期望的输出是:{(2,2)}
.
我需要找到出现频率最高的元素。如果有元素重复同样多次,它必须 return 多个值。
我尝试用三个列表的交集来解决它,但它打印出 {(2,1), (2,2)}
,而不是 {(2,2)}
,因为元素 (2,2)
在第一个列表中重复了两次.
我看到了一些 import collections
的示例,但我不理解它们,所以我不知道如何更改代码以适合我的问题。
我还尝试了以下方法:
seen = set()
repeated = set()
for l in pairs:
for i in set(l):
if i in seen:
repeated.add(i)
if i in repeated:
repeated.add(i)
else:
seen.add(i)
但仍然没有return正确答案。
collections.Counter()
会起作用...您只需要弄清楚如何传递嵌套列表中的所有对,您可以通过列表理解来做到这一点。例如:
from collections import Counter
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
counts = Counter(pair for l in pairs for pair in l)
counts.most_common(1)
# [((2, 2), 4)]
如果出现平局,您将需要查看排名靠前的选项并挑出数量相同的选项。您可以通过查看 counts.most_common()
.
itertools.groupby
是处理这种情况的常用方法。例如,如果您有平局,您可以获得所有排名靠前的条目,例如:
from collections import Counter
from itertools import groupby
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1), (3, 2)]]
counts = Counter(pair for l in pairs for pair in l)
count, groups = next(groupby(counts.most_common(), key=lambda t: t[1]))
[g[0] for g in groups]
# [(2, 2), (3, 2)]
不使用 collections
中的 Counter
方法的替代解决方案:
def get_freq_tuple(data):
counts = {}
for pairs in data:
for pair in pairs:
counts[pair] = counts.get(pair, 0) + 1
return [pair for pair in counts if counts[pair] == max(counts.values())]
if __name__ == "__main__":
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1),
(3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
print(get_freq_tuple(pairs))
输出:
[(2, 2)]
解释:
- 计算每个元组的出现次数并将它们存储在字典中。字典的键是元组,值是出现。
- 根据元组的最大出现次数过滤字典中的元组。
免责声明:
- 使用
collections
中的Counter
方法效率更高。
参考文献:
正如评论中所暗示的那样,defaultdict
非常有帮助。
from collections import defaultdict
我们有“成对”,但由于您想要 所有 列表中出现频率最高的,我们会将其展平。
pairs = [[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 2), (3, 1), (2, 1), (3, 1), (3, 2), (3, 3), (3, 2), (2, 2)],
[(2, 2), (2, 1)],
[(1, 1), (1, 2), (2, 2), (2, 1)]]
flat_pairs = [tpl for lst in pairs for tpl in lst]
现在我们将创建一个默认为零的 defaultdict
来保存我们的计数,并迭代 flat_pairs 以将计数添加到字典中。
counts = defaultdict(lambda: 0)
for tpl in flat_pairs:
counts[tpl] += 1
或者我们可以跳过展平阶段:
counts = defaultdict(lambda: 0)
for lst in pairs:
for tpl in lst:
counts[tpl] += 1
我们可以通过对字典的值使用 max
来找到最大计数值,然后使用列表理解来获得具有最大计数的一个或多个元组。
max_count = max(counts.values())
max_count_tuples = [tpl for tpl, count in counts.items() if count == max_count]