Python 查找字符串中最常用的字符

Python 查找字符串中最常用的字符,python,algorithm,optimization,time-complexity,Python,Algorithm,Optimization,Time Complexity,我发现这个编程的问题,而在看一份招聘启事上如此。我觉得这很有趣,作为一名Python初学者,我试图解决这个问题。然而,我觉得我的解决方案相当…混乱…有人能提出任何建议来优化它或使它更干净吗?我知道这很琐碎,但我写得很开心。注:Python 2.6 问题: import string def find_max_letter_count(word): alphabet = string.ascii_lowercase dictionary = {} for letter

我发现这个编程的问题,而在看一份招聘启事上如此。我觉得这很有趣,作为一名Python初学者,我试图解决这个问题。然而,我觉得我的解决方案相当…混乱…有人能提出任何建议来优化它或使它更干净吗?我知道这很琐碎,但我写得很开心。注:Python 2.6

问题:

import string

def find_max_letter_count(word):

    alphabet = string.ascii_lowercase
    dictionary = {}

    for letters in alphabet:
        dictionary[letters] = 0

    for letters in word:
        dictionary[letters] += 1

    dictionary = sorted(dictionary.items(), 
                        reverse=True, 
                        key=lambda x: x[1])

    for position in range(0, 26):
        print dictionary[position]
        if position != len(dictionary) - 1:
            if dictionary[position + 1][1] < dictionary[position][1]:
                break

find_max_letter_count("helloworld")
>>> 
('l', 3)
为接收字符串并返回该字符串中出现最多的字母的函数编写伪代码(或实际代码)

我的尝试:

import string

def find_max_letter_count(word):

    alphabet = string.ascii_lowercase
    dictionary = {}

    for letters in alphabet:
        dictionary[letters] = 0

    for letters in word:
        dictionary[letters] += 1

    dictionary = sorted(dictionary.items(), 
                        reverse=True, 
                        key=lambda x: x[1])

    for position in range(0, 26):
        print dictionary[position]
        if position != len(dictionary) - 1:
            if dictionary[position + 1][1] < dictionary[position][1]:
                break

find_max_letter_count("helloworld")
>>> 
('l', 3)
更新示例:

find_max_letter_count("balloon") 
>>>
('l', 2)
('o', 2)

有很多方法可以做到这一点。例如,您可以使用该类(在Python 2.7或更高版本中):

如果没有,您可以手动理货(2.5或更高版本有
defaultdict
):


话虽如此,您的实现没有太大的问题。

以下是我要做的几件事:

  • 使用
    collections.defaultdict
    而不是手动初始化的
    dict
  • 使用内置的排序和最大值函数,如
    max
    ,而不是自己计算-这更容易
以下是我的最终结果:

from collections import defaultdict

def find_max_letter_count(word):
    matches = defaultdict(int)  # makes the default value 0

    for char in word:
        matches[char] += 1

    return max(matches.iteritems(), key=lambda x: x[1])

find_max_letter_count('helloworld') == ('l', 3)

如果您使用的是Python2.7,那么可以通过使用collections模块快速完成这项工作。 collections是一个高性能的数据结构模块。阅读更多

如果您希望所有字符的计数都达到最大值,那么您可以对目前提出的两个想法中的一个进行修改:

import heapq  # Helps finding the n largest counts
import collections

def find_max_counts(sequence):
    """
    Returns an iterator that produces the (element, count)s with the
    highest number of occurrences in the given sequence.

    In addition, the elements are sorted.
    """

    if len(sequence) == 0:
        raise StopIteration

    counter = collections.defaultdict(int)
    for elmt in sequence:
        counter[elmt] += 1

    counts_heap = [
        (-count, elmt)  # The largest elmt counts are the smallest elmts
        for (elmt, count) in counter.iteritems()]

    heapq.heapify(counts_heap)

    highest_count = counts_heap[0][0]

    while True:

        try:
            (opp_count, elmt) = heapq.heappop(counts_heap)
        except IndexError:
            raise StopIteration

        if opp_count != highest_count:
            raise StopIteration

        yield (elmt, -opp_count)

for (letter, count) in find_max_counts('balloon'):
    print (letter, count)

for (word, count) in find_max_counts(['he', 'lkj', 'he', 'll', 'll']):
    print (word, count)
例如,这将产生:

lebigot@weinberg /tmp % python count.py
('l', 2)
('o', 2)
('he', 2)
('ll', 2)
这适用于任何序列:单词,但也适用于['hello','hello','bonjour'],例如


heapq
结构在查找序列中的最小元素时非常有效,无需对其进行完全排序。另一方面,由于字母表中没有那么多字母,您可能还可以遍历已排序的计数列表,直到再也找不到最大计数,而不会导致任何严重的速度损失。

以下是使用字典查找最常见字符的方法

message = "hello world"
d = {}
letters = set(message)
for l in letters:
    d[message.count(l)] = l

print d[d.keys()[-1]], d.keys()[-1]
frequencies
是将字符计数为
(字符,计数)
的元组列表。我们使用
count
将max应用于元组,并返回该元组的
字符。如果出现平局,此解决方案将只选择一个。

问题:
#file:filename
#quant:no of frequent words you want

def frequent_letters(file,quant):
    file = open(file)
    file = file.read()
    cnt = Counter
    op = cnt(file).most_common(quant)
    return op   
字符串中最常用的字符 输入字符串中出现的最大字符数

方法1:

a = "GiniGinaProtijayi"

d ={}
chh = ''
max = 0 
for ch in a : d[ch] = d.get(ch,0) +1 
for val in sorted(d.items(),reverse=True , key = lambda ch : ch[1]):
    chh = ch
    max  = d.get(ch)


print(chh)  
print(max)  
方法2:

a = "GiniGinaProtijayi"

max = 0 
chh = ''
count = [0] * 256 
for ch in a : count[ord(ch)] += 1
for ch in a :
    if(count[ord(ch)] > max):
        max = count[ord(ch)] 
        chh = ch

print(chh)        
方法3:

import collections

a = "GiniGinaProtijayi"

aa = collections.Counter(a).most_common(1)[0]
print(aa)

我注意到,即使最常用的字符数量相等,大多数答案也只返回一个条目。例如“iii 444 yyy 999”。有相等数量的空间,i's,4's,y's和9's。解决方案应该包括所有内容,而不仅仅是字母i:

sentence = "iii 444 yyy 999"

# Returns the first items value in the list of tuples (i.e) the largest number
# from Counter().most_common()
largest_count: int = Counter(sentence).most_common()[0][1]

# If the tuples value is equal to the largest value, append it to the list
most_common_list: list = [(x, y)
                         for x, y in Counter(sentence).items() if y == largest_count]

print(most_common_count)

# RETURNS
[('i', 3), (' ', 3), ('4', 3), ('y', 3), ('9', 3)]

这里有一种使用FOR循环和COUNT()的方法


我这样做的方式没有使用Python本身的内置函数,只使用循环和if语句

def most_common_letter():
    string = str(input())
    letters = set(string)
    if " " in letters:         # If you want to count spaces too, ignore this if-statement
        letters.remove(" ")
    max_count = 0
    freq_letter = []
    for letter in letters:
        count = 0
        for char in string:
            if char == letter:
                count += 1
        if count == max_count:
            max_count = count
            freq_letter.append(letter)
        if count > max_count:
            max_count = count
            freq_letter.clear()
            freq_letter.append(letter)
    return freq_letter, max_count

这可以确保您获得使用最多的每个字母/字符,而不仅仅是一个。它还返回它发生的频率。希望这对您有所帮助:)

附带说明:您应该阅读推荐的Python编码风格的文档。方法应该是snake_大小写而不是mixedCase。可能重复的可能重复的…谢谢你的回答(你也是Chris Morgan),但我想我忘了提到,如果多个字符是最常见的,它们都应该输出。(例如“abcdefg”输出a=1、b=1等)我认为这是最棘手的部分,因此最后出现了混乱。我已经编辑了这个问题。挑剔:
字母
字母
更正确,因为它是一个只包含一个字母的变量。@EOL:true;我并没有根据他所拥有的重命名那个变量——我自己把它命名为
char
,我想,因为它不仅仅是一封信……感谢您提供这个代码片段,它可能会提供一些有限的、即时的帮助。通过说明为什么这是一个很好的问题解决方案来正确解释它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的回答中添加一些解释,包括您所做的假设。具体来说,
Counter
来自何处?必须使用“from collections import Counter”命令导入计数器。请您的回答显示附加信息,而不是将其作为注释写入。评论可以消失得无影无踪,所以它确实需要成为你答案的一部分。非常感谢。
sentence = "iii 444 yyy 999"

# Returns the first items value in the list of tuples (i.e) the largest number
# from Counter().most_common()
largest_count: int = Counter(sentence).most_common()[0][1]

# If the tuples value is equal to the largest value, append it to the list
most_common_list: list = [(x, y)
                         for x, y in Counter(sentence).items() if y == largest_count]

print(most_common_count)

# RETURNS
[('i', 3), (' ', 3), ('4', 3), ('y', 3), ('9', 3)]
w = input()
r = 1
for i in w:
    p = w.count(i)
    if p > r:
        r = p
        s = i
print(s)
def most_common_letter():
    string = str(input())
    letters = set(string)
    if " " in letters:         # If you want to count spaces too, ignore this if-statement
        letters.remove(" ")
    max_count = 0
    freq_letter = []
    for letter in letters:
        count = 0
        for char in string:
            if char == letter:
                count += 1
        if count == max_count:
            max_count = count
            freq_letter.append(letter)
        if count > max_count:
            max_count = count
            freq_letter.clear()
            freq_letter.append(letter)
    return freq_letter, max_count