найти количество гласных в строке

У меня есть строка букв в качестве ввода.
ввод:

my_str = 'soumendra_in_stackoverflow'

Я хочу, чтобы вывод, как показано ниже. Где все гласные должны быть напечатаны вместе с их соответствующим количеством в словаре.
необходим вывод:

{'a': 2, 'e': 2, 'i': 1, 'o': 3, 'u': 1}

Для этого я написал следующую программу:

ans_dict = {}
for letter in my_str:
    if letter in ['a', 'e', 'i', 'o', 'u']:
        ans_dict[letter] = ans_dict.get(letter, 0) + 1
print(ans_dict)

Оно работает. Однако как написать ту же самую логику в одной строке (возможно, используя понимание словаря) без использования collections.Counter?
Я пробовал это, но это не помогло.

{x: + 1 for x in a if x in ['a', 'e', 'i', 'o', 'u'] }

person Soumendra    schedule 22.09.2018    source источник
comment
Почему бы не использовать Counter? Похоже, лучший инструмент для этого. Вы можете сделать это с пониманием словаря, но в результате вы будете перебирать строку пять раз, делая ее менее эффективной.   -  person Willem Van Onsem    schedule 22.09.2018
comment
stackoverflow.com/questions/12833512/ См. первый и второй ответ.   -  person    schedule 22.09.2018
comment
stackoverflow.com/questions/12833512/ См. первый и второй ответ.   -  person    schedule 22.09.2018
comment
stackoverflow.com/questions/12833512/   -  person    schedule 22.09.2018
comment
@Gozzah: Я думаю, что связанные вопросы решают другую проблему: здесь нас интересует количество гласных в строке, а не строки (!) в списке, которые начинаются с гласной. Да, есть некоторое совпадение, но это две разные проблемы в строгом смысле.   -  person Willem Van Onsem    schedule 22.09.2018
comment
Я считаю, что если вы используете набор для поиска с оператором in, это будет быстрее.   -  person N Chauhan    schedule 22.09.2018


Ответы (1)


Вы можете использовать str.count и, таким образом, написать понимание словаря с помощью:

result = { v: my_str.count(v) for v in "aeiou" }

Но это, таким образом, приводит к перечислению my_str пяти раз. Однако, как говорит @DSM, .count(..) обычно работает довольно быстро (я предполагаю, что он реализован на уровне интерпретатора, поэтому ему не нужно «перебирать» коллекцию).

Лично я думаю, что Counter здесь было бы лучше, так как

  1. он разработан именно для подсчета вещей, и, кроме того, он оборачивает данные в интерфейс, который будет обеспечивать соблюдение ограничений (если нет ошибки в Counter, подсчеты определенно будут правильными, тогда как пользовательский алгоритм все еще может иметь " глупая" ошибка, да тут это очень маловероятно, но этого все же лучше избегать); и
  2. он предоставляет удобный интерфейс для выполнения всевозможных действий с этими счетчиками (например, counter1 & counter2 создаст новый Counter с минимальным количеством каждого элемента).
person Willem Van Onsem    schedule 22.09.2018
comment
Обратите внимание, что пять — это неправильный акцент; count настолько быстр, что при небольшом количестве ключей на самом деле более эффективно использовать count. Только пять, это примерно на порядок быстрее на длинных строках. Концептуальные аргументы сильнее (хотя даже здесь они становятся туманными в пределе — например, мы все пишем some_str.count(","), а не Counter(some_str)[","]). - person DSM; 22.09.2018
comment
@DSM: я думаю, что .count(..) действительно быстрее, поскольку он реализован на уровне интерпретатора (ну, определение строки Python). Но мне не очень нравится многократно повторять коллекцию, если в этом нет необходимости :). С точки зрения большого о, он будет масштабироваться как O(m n), так что это означает, что если количество символов, которые мы должны подсчитать, довольно велико (например, все китайские символы Юникода), это приведет к узкому месту. . Но вы правы, что для гласных это может быть быстрее или с незначительной разницей). - person Willem Van Onsem; 22.09.2018