【问题标题】:Arrange elements with same count in alphabetical order按字母顺序排列具有相同计数的元素
【发布时间】:2017-09-13 20:15:30
【问题描述】:

Python Collection Counter.most_common(n) 方法返回前 n 个元素及其计数。但是,如果两个元素的计数相同,如何返回按字母顺序排序的结果?

例如:对于像:BBBAAACCD 这样的字符串,对于“2-最常见”元素,我希望结果是指定的 n = 2

[('A', 3), ('B', 3), ('C', 2)]

而不是:

[('B', 3), ('A', 3), ('C', 2)]

请注意,虽然AB 具有相同的频率,但A 在结果列表中位于B 之前,因为它按字母顺序位于B 之前。

[('A', 3), ('B', 3), ('C', 2)]

我怎样才能做到这一点?

【问题讨论】:

  • @HarshaW 不,它不是重复的。我刚刚更新了我的问题以澄清我想要实现的目标。如果您有任何想法,请查看并告诉我。

标签: python counter python-collections


【解决方案1】:
from collections import Counter
print(sorted(Counter('AAABBBCCD').most_common(3)))

这个问题似乎是重复的 How to sort Counter by value? - python

【讨论】:

  • 这不起作用。如果您使“A”不是最常见的,它会撤消 most_common 并按字母顺序返回它。
【解决方案2】:

我将首先按字母顺序对您的输出数组进行排序,然后再按大多数出现的次数进行排序,这将保持字母顺序:

from collections import Counter
alphabetic_sorted = sorted(Counter('BBBAAACCD').most_common(), key=lambda tup: tup[0])
final_sorted = sorted(alphabetic_sorted, key=lambda tup: tup[1], reverse=True)
print(final_sorted[:3])

输出:

[('A', 3), ('B', 3), ('C', 2)]

【讨论】:

  • 它不适用于'qqweertyuiopasdfghjklzxcvbnm' 字符串
  • 感谢您的评论。我将解决方案更改为可以解决您的示例的更通用的解决方案!
【解决方案3】:

我会去:

sorted(Counter('AAABBBCCD').most_common(), key=lambda t: (-t[1], t[0]))

这对计数进行降序排序(因为它们已经如此,这应该会更高效),然后在每个相等的计数组中按名称升序排序

【讨论】:

  • 但是当用户想要“前 2 个值”时,这不包括重复项,例如见my answer
  • 哦,问题中没有明确说明
  • 可能,但它隐含在输出中。我同意这个问题可以写得更清楚(我会尝试这样做)。
【解决方案4】:

这里有两个问题:

  1. 在考虑前 n 个最常见的值时包含重复项不包括重复项
  2. 如有重复,请按字母顺序排列。

到目前为止,没有一个解决方案可以解决第一个问题。您可以使用带有 itertools unique_everseen recipe 的堆队列(也可在 3rd 方库中使用,例如 toolz.unique)来计算第 n 个最大计数。

然后将sorted 与自定义键一起使用。

from collections import Counter
from heapq import nlargest
from toolz import unique

x = 'BBBAAACCD'

c = Counter(x)
n = 2
nth_largest = nlargest(n, unique(c.values()))[-1]

def sort_key(x):
    return -x[1], x[0]

gen = ((k, v) for k, v in c.items() if v >= nth_largest)
res = sorted(gen, key=sort_key)

[('A', 3), ('B', 3), ('C', 2)]

【讨论】:

    【解决方案5】:

    这是我在面试考试中遇到的问题之一,但没能做到。回到家睡了一会儿,解决方案出现在我的脑海中。

    from collections import Counter
    
    
    def bags(list):
        cnt = Counter(list)
        print(cnt)
        order = sorted(cnt.most_common(2), key=lambda i:( i[1],i[0]), reverse=True)
        print(order)
        return order[0][0]
    
    
    print(bags(['a','b','c','a','b']))
    

    【讨论】:

    • 但如果您将在列表中使用更多元素,则结果不会按字母顺序排序,例如尝试使用 print(bags(['a','b','c','a','b', 'c', 'c', 'd', 'd']))most_common(3) 有时它会返回 [('c', 3), ('b', 2), ('a', 2)] 但我总是等待 @ 987654325@
    【解决方案6】:
    from collections import Counter
    
    
    s = 'qqweertyuiopasdfghjklzxcvbnm'
    
    s_list = list(s)
    
    elements = Counter(s_list).most_common()
    
    print(elements)
    alphabet_sort = sorted(elements, key=lambda x: x[0])
    print(alphabet_sort)
    num_sort = sorted(alphabet_sort, key=lambda x: x[1], reverse=True)
    print(num_sort)
    

    如果需要切片:

    print(num_sort[:3])
    

    【讨论】:

      【解决方案7】:
      s = "BBBAAACCD"    
      p = [(i,s.count(i)) for i in sorted(set(s))]
      

      **如果您可以不使用计数器。

      【讨论】:

        【解决方案8】:

        虽然这个问题已经有点老了,但我想提出一个非常简单的解决方案来解决这个问题,它只涉及在创建 Counter 对象之前对 Counter() 的输入进行排序。如果您随后调用 most_common(n),您将获得按字母顺序排序的前 n 个条目。

        from collections import Counter
        
        char_counter = Counter(sorted('ccccbbbbdaef'))
        for char in char_counter.most_common(3):
          print(*char)
        

        导致输出:

        b 4
        c 4
        a 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-09
          • 2013-10-16
          • 1970-01-01
          相关资源
          最近更新 更多