我对解决以下问题的简洁(+最佳)方法感兴趣,因为我很好奇如何以Pythonic方式执行它。在执行单独的任务时,我尝试创建一个包含任意元素的 collections.Counter
字典:
d = Counter({('A','C'): 4, ('B','D','E'): 3, ..., ('A','G','V','X','Z'): 1, ('L','Z'): 1})
这里,每个元素都是一个元组,由 2 个或更多字符组成。我的目标是创建一个列表,其中包含最常见的项目并且重复项按照元组中的元素数量唯一。例如,解决方案可能如下所示:
d_sample = Counter({('A', 'C'): 4, ('B', 'D', 'E'): 3, ('A' ,'D'): 3, ('C', 'D', 'E'): 3,
('A', 'B', 'C', 'D', 'E'): 2, ('A', 'C', 'D', 'E'): 1,
('B', 'C', 'D', 'E'): 1, ('D', 'E'): 1})
result = [('A', 'C'), ('B', 'D', 'E'), ('C', 'D', 'E'), ('A', 'B', 'C', 'D', 'E'),
('A', 'C', 'D', 'E'), ('B', 'C', 'D', 'E')]
这里选择了('A', 'C')
,因为它是包含两个计数最高的元素的元组。 ('B', 'D', 'E')
和 ('C', 'D', 'E')
都被选中,因为它们是带有计数最高的三个元素。 结果
列表中的其他元素也是如此。
我想到的方法是使用for
循环从d
中提取多个列表,按元素数量分隔:for i in range(2, # 使用另一个 for 循环的最大元素)
。从那里,我使用另一个 for
循环和 max()
计算频率最高的项目。
# pseudo-example:
maxval = 2
for x in d:
if len(x[0]) > maxval:
maxval = len(x[0])
counter_list = [[] * n for n in range(maxval-2)]
for x in d:
counter_list[len(x[0])-2].append(x)
## selecting max per list
正如所阐述的,这看起来根本不是 Pythonic 和最佳的。任何能够更优化地完成任务的见解将不胜感激。
最佳答案
这是O(n),我认为渐近不可能比这更好。
highest_count_for_length = {}
result = []
for tup, count in d.items():
try:
if highest_count_for_length[len(tup)] == count:
result.append(tup)
except KeyError:
# we haven't seen this length yet
highest_count_for_length[len(tup)] = count
result.append(tup)
它确实依赖于输入已经按值排序的事实。
关于Pythonic 方式来计算 Counter 中最常见的重复项目,分别按元素数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71976351/