如何在字符串列表中找到主要字母

时间:2019-06-04 20:18:09

标签: python python-2.7

我想检查字符串中每个位置最常出现在该位置的字符是什么。 如果有更多相同的频率,请保留第一个。保证列表中的所有字符串都具有相同的长度!

我尝试了以下方法:

print(max(((letter, strings.count(letter)) for letter in strings), key=lambda x:[1])[0])

但是我得到:mistulqagic

我无法弄清楚我的代码出了什么问题。

我的字符串列表如下:

输入:strings = ['mistul', 'aidteh', 'mhfjtr', 'zxcjer']

输出:mister

说明:在第一个位置上, m 出现两次。其次, i 出现两次。第三,没有主要字符,因此我们选择第一个字符,即 s 。在第四位置,我们两次 t j ,但是您看到的是第一个 t ,所以我们和他在一起,在第五位置我们有两次 e ,最后一次是 r

另一个例子:

输入:['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']

输出:magic

输入:['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv', 'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq', 'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq', 'djtfzr', 'uenleo']

预期输出:secret

有帮助吗?

3 个答案:

答案 0 :(得分:1)

最后是zip()的用例:-)

如果您喜欢加密代码,甚至可以在一条语句中完成:

def solve(strings):
    return ''.join([max([(letter, letters.count(letter)) for letter in letters], key=lambda x: x[1])[0] for letters in zip(*strings)])

但是我更喜欢可读性强的版本:

def solve(strings):
    result = ''
    # "zip" the strings, so in the first iteration `letters` would be a list
    # containing the first letter of each word, the second iteration it would
    # be a list of all second letters of each word, and so on...
    for letters in zip(*strings):
        # Create a list of (letter, count) pairs:
        letter_counts = [(letter, letters.count(letter)) for letter in letters]
        # Get the first letter with the highest count, and append it to result:
        result += max(letter_counts, key=lambda x: x[1])[0]
    return result

# Test function with input data from question:
assert solve(['mistul', 'aidteh', 'mhfjtr', 'zxcjer']) == 'mister'
assert solve(['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn',
              'mzsev', 'saqbl', 'myead']) == 'magic'
assert solve(['sacbkt', 'tnqaex', 'vhcrhl', 'obotnq', 'vevleg', 'rljnlv',
              'jdcjrk', 'zuwtee', 'xycbvm', 'szgczt', 'imhepi', 'febybq',
              'pqkdfg', 'swwlds', 'ecmrut', 'buwruy', 'icjwet', 'gebgbq',
              'djtfzr', 'uenleo']) == 'secret'

更新

@dun提出了使用max()函数的更聪明的方法,这使得单线实际上非常易读:-)

def solve(strings):
    return ''.join([max(letters, key=letters.count) for letters in zip(*strings)])

答案 1 :(得分:0)

在这里使用collections.Counter()是一个不错的策略。这是一种实现方法:

from collections import Counter

def most_freq_at_index(strings, idx):
  chars = [s[idx] for s in strings]
  char_counts = Counter(chars)
  return char_counts.most_common(n=1)[0][0]

strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 
           'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']

result = ''.join(most_freq_at_index(strings, idx) for idx in range(5))
print(result) 
## 'magic'

答案 2 :(得分:0)

如果您想要更多的手册,而又没有Python库的魔力,可以执行以下操作:

def f(strings):
    dic = {}
    for string in strings:
        for i in range(len(string)):
            word_dic = dic.get(i, { string[i]: 0 })
            word_dic[string[i]] = word_dic.get(string[i], 0) + 1
            dic[i] = word_dic
    largest_string = max(strings, key = len)
    result = ""
    for i in range(len(largest_string)):
        result += max(dic[i], key = lambda x : dic[i][x])
    return result
strings = ['qagic', 'cafbk', 'twggl', 'kaqtc', 'iisih', 'mbpzu', 'pbghn', 'mzsev', 'saqbl', 'myead']
f(strings)
'magic'