2015-03-30 2 views
-1

Я пытаюсь подсчитать количество строк с гласными в них, учитывая список списков строк. Я не уверен, что я делаю неправильно. Любая помощь будет оценена по достоинству.Подсчет количества строк с гласными в списке списка строк

def count_vowels(list): 
    """ (list of list of str) -> int 

    Return the number of vowel-inclusive strings in a list of list of str. 

    >>> list = [['X', 'OW1'], ['Z', 'AH1', 'R']] 
    >>> count_vowels(list) 
    2 
    """ 

    for sublist in list: 
     num_vowels = 0 
     for item in sublist: 
      if item in "aeiouAEIOU": 
       num_vowels += 1 
    return num_vowels     
+0

Так что же происходит? Какой результат вы получаете и что вы ожидаете получить вместо этого? –

+0

Не используйте 'list' в качестве аргумента. –

+0

@MartijnPieters Я получаю 0, когда мне нужно получить 2. – Ingrid

ответ

3

Каждый item является полной строкой. AH1 не встречается в "aeiouAEIOU", поскольку в строке гласного нет такой подстроки.

Вы также сбросите num_vowels всего за подсписок, так что вы получите только итоговое значение для последнего элемента к моменту возврата значения.

Вы могли цикл по каждому из гласных и проверить те индивидуально:

def count_vowels(lst): 
    num_vowels = 0 
    for sublist in lst: 
     for item in sublist: 
      for vowel in "aeiouAEIOU": 
       if vowel in item: 
        num_vowels += 1 
        break 
    return num_vowels 

Я использовал имя lst вместо list, чтобы не маскировать встроенного типа. break завершает цикл for vowel, когда вы определили, что в нем действительно есть хотя бы один гласный.

Это еще не все, что эффективно. Вы можете уменьшить количество тестов на lowercasing детали и тестирования только для строчной гласные:

def count_vowels(lst): 
    num_vowels = 0 
    for sublist in lst: 
     for item in sublist: 
      item = item.lower() 
      for vowel in "aeiou": 
       if vowel in item: 
        num_vowels += 1 
        break 
    return num_vowels 

Вы можете использовать набор перекрестки, чтобы найти, если есть пересечение с гласными набором:

def count_vowels(lst): 
    num_vowels = 0 
    vowels = set('aeiou') 
    for sublist in lst: 
     for item in sublist: 
      if vowel.intersection(item.lower()) 
       num_vowels += 1 
    return num_vowels 

или используйте any() function с выражением генератора; он будет делать то же самое, что и цикл for с break; она выходит рано, когда соответствующий гласный было найдено:

def count_vowels(lst): 
    num_vowels = 0 
    for sublist in lst: 
     for item in sublist: 
      item = item.lower() 
      if any(vowel in item for vowel in "aeiou") 
       num_vowels += 1 
    return num_vowels 

Если вы используете sum() function вы можете свернуть подсчета слов в

def count_vowels(lst): 
    vowels = set('aeiou') 
    return sum(1 
     for sublist in lst 
     for item in sublist 
     if vowel.intersection(item.lower())) 
+2

Ey! Marty, 'list' как переменная !! –

+1

@BhargavRao: poko poko, все хорошие вещи требуют времени. –

+0

Эта функция может быть упрощена до двух строк с функциями 'any' и' sum'. –

1

Вы пытаетесь найти, если слово имеет гласную по делает s in "aeiouAEIOU", что не совпадает с «строка имеет гласный». Вы можете сделать это:

if any(c in item for c in "aeiouAEIOU"): 
    num_vowels += 1 

Или вы могли бы сделать это:

if len(set(item) & set("aeiouAEIOU")) > 0: #this may be faster if you precompute set("aeiouAEIOU") 
    num_vowels += 1 

Или, если вы хотите использовать регулярное выражение:

r = re.compile("[aeiouAEIOU]") #compute this one out of your loop 
if r.search(item): 
    num_vowels += 1 

Все будет работать, до вас, чтобы выяснить, какие один быстрее.

+0

'len (...)> 0' можно удалить вообще; пустое значение false в булевом контексте. –

+0

Правда, но у OP уже есть проблемы с простой программой, поэтому я думаю, что эту дополнительную многословие легче понять. – vermillon

0

Просто распаковать список списков в один список, то проверьте гласные:

def count_vowels(data): 
    data = itertools.chain.from_iterable(data) # data is first arg 
    return sum(1 for i in data if any(j in i for j in 'aeiouAEIOU')) 

В первой строке, вложенный список составляется в виде единого списка. Вторая строка проверяет любые гласные, в каждом элементе возвращается сумма элементов, которые положили положительный результат в проверке гласных с использованием встроенных методов и any.

Смежные вопросы