Как вернуть наиболее часто встречающиеся буквы в строке и упорядочить их по частоте подсчета - PullRequest
0 голосов
/ 29 октября 2018

У меня есть эта строка: s = "china construction bank". Я хочу создать функцию, которая возвращает 3 наиболее часто встречающихся символа и упорядочивает их по частоте их появления и количеству их появления, но если 2 символа появляются одинаковое количество раз, их следует упорядочить в соответствии с их алфавитным порядком. Я также хочу напечатать каждый символ в отдельной строке.

Я уже создал этот код:

from collections import Counter
def ordered_letters(s, n=3):
    ctr = Counter(c for c in s if c.isalpha())
    print ''.join(sorted(x[0] for x in ctr.most_common(n)))[0], '\n', ''.join(sorted(x[0] for x in ctr.most_common(n)))[1], '\n', ''.join(sorted(x[0] for x in ctr.most_common(n)))[2]`

Этот код, примененный к приведенной выше строке, даст:

a 
c 
n

Но это не то, что я действительно хочу, а то, что я хотел бы получить в результате:

1st most frequent: 'n'. Appearances: 4
2nd most frequent: 'c'. Appearances: 3
3rd most frequent: 'a'. Appearances: 2

Я застрял в той части, где я должен печатать в алфавитном порядке символы с одинаковыми частотами. Как я мог это сделать?

Большое спасибо заранее

Ответы [ 4 ]

0 голосов
/ 29 октября 2018

Вы можете использовать defaultdict для создания словаря со значениями, установленными в 0, и увеличивать их в любое время, когда они встречаются. Сначала вы сортируете по алфавиту, затем по вхождению. Это гарантирует, что любые значения, которые соответствуют, имеют приоритет в алфавитном порядке.

например:

from collections import defaultdict
a = {} 
a = defaultdict(lambda:0,a)

s = "china construction bank"

for letter in s:
    if letter != ' ':
        a[letter] += 1

top_three = sorted(sorted(a.items(), key=lambda x: x[0]), key=lambda x: x[1], reverse=True)[:3]

counter = 0
for letter, occurance in top_three:
    counter += 1
    print(str(counter) + " Most frequent: " + letter + " . Appearances: " + str(occurance))

Это дает вывод, соответствующий указанному вами:

1 Most frequent: n . Appearances: 4
2 Most frequent: c . Appearances: 3
3 Most frequent: a . Appearances: 2
0 голосов
/ 29 октября 2018

Вы можете использовать heapq.nlargest с пользовательским ключом сортировки. Мы используем -ord(k) в качестве вторичного сортировщика для сортировки по возрастанию букв. Использование очереди кучи лучше, чем sorted, так как нет необходимости сортировать все элементы в вашем Counter объекте.

from collections import Counter
from heapq import nlargest

def ordered_letters(s, n=3):
    ctr = Counter(c.lower() for c in s if c.isalpha())

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

    for idx, (letter, count) in enumerate(nlargest(n, ctr.items(), key=sort_key), 1):
        print('#', idx, 'Most frequent:', letter, '.', 'Appearances:', count)

ordered_letters("china construction bank")

# 1 Most frequent: n . Appearances: 4
# 2 Most frequent: c . Appearances: 3
# 3 Most frequent: a . Appearances: 2
0 голосов
/ 29 октября 2018

Сортировка кортежей из Counter обычным образом , но с первым аргументом - самим счетчиком - отрицательными.В результате получается обратный список, но с элементом кортежа second , отсортированным по алфавиту.Затем возьмите последние n предметов.

from collections import Counter

ordinal = lambda n: "%d%s" % (n,"tsnrhtdd"[(n/10%10!=1)*(n%10<4)*n%10::4])

def ordered_letters(s, n=3):
    ctr = Counter(c for c in s if c.isalpha())
    ctr = sorted(ctr.items(), key=lambda x: (-x[1], x[0]))[:n]
    for index,value in enumerate(ctr):
        print "{:s} most frequent: '{:}'. Appearances: {:}".format(ordinal(index+1),value[0],value[1])

s = "achina aconstruction banck"
ordered_letters(s, n=3)

Результат:

1st most frequent: 'a'. Appearances: 4
2nd most frequent: 'c'. Appearances: 4
3rd most frequent: 'n'. Appearances: 4

(Чумовая ordinal Лямбда любезно предоставлена ​​ Замена порядковых чисел )

0 голосов
/ 29 октября 2018

Вы можете отсортировать c.most_common() с помощью пользовательской клавиши, которая сначала учитывает нисходящий порядок частоты, а затем - алфавитный порядок (примечание lambda x: (-x[1], x[0])):

from collections import Counter

def ordered_letters(s, n=3):
    c = Counter(s.replace(' ', ''))
    top_n = sorted(c.most_common(), key=lambda x: (-x[1], x[0]))[:n]
    for i, t in enumerate(top_n):
        c, f = t
        if i == 0: print('1st most frequent', c + '.', 'Appearances:', f)
        elif i == 1: print('2nd most frequent', c + '.', 'Appearances:', f)
        elif i == 2: print('3rd most frequent', c + '.', 'Appearances:', f)
        else: print(str(i + 1) + 'th most frequent', c + '.', 'Appearances', f)

sent = "china construction bank"
ordered_letters(sent, 5)
# 1st most frequent n. Appearances: 4                                                                                                                       
# 2nd most frequent c. Appearances: 3                                                                                                                       
# 3rd most frequent a. Appearances: 2                                                                                                                       
# 4th most frequent i. Appearances 2                                                                                                                        
# 5th most frequent o. Appearances 2  
...