2015-09-14 3 views
3

Наша цель - найти строку ввода пользователя и подсчитать, сколько гласных найдено внутри нее. К сожалению, я застрял здесь, любая помощь?Python Lambda Practice

def numVowels(s): 
    vowels= "AEIOUaeiou" 
    if s == '': 
     return 0 
    else: 
     totalVowels = list(filter(lambda vowels:sum("AEIOUaeiou"), s)) 
     print(len((totalVowels))) 
+2

проверить, какие «лямбда-гласные»: сумма («AEIOUaeiou») 'делает – acushner

+0

ваш код действительно ничего не делает из того, что я могу сказать –

+0

Застрял как? Вы пытаетесь 'sum()' гласные, что не имеет смысла. – AChampion

ответ

2

я покажу три подхода в парах, каждый раз делая это с помощью lambda, а затем с помощью выражения эквивалентного генератора. Важно понимать, что выражения генераторов (и списки) представляют собой просто синтаксический сахар для пары операций map и filter и могут быть переведены взад и вперед механически. Однако способ выражения/понимания обычно считается более Pythonic.

Ключом к такой проблеме является то, что вам нужно выяснить, что вы хотите сделать в фильтре и что вы хотите делать на карте. То есть: вы должны иметь возможность писать код, который смотрит на один элемент и решает, включать его или нет; а также код, который смотрит на один элемент и преобразует его в более полезную ценность.

Поэтому, прежде чем показать код, давайте удостоверимся, что мы можем:

  • дали письмо, определить, является ли оно содержится в нашей vowels строке. Это тривиально: мы можем буквально спросить Python, является ли letter in vowels (предполагается, что letter - это некоторая переменная, но будьте осторожны с тем, что с vowels, являющимся строкой, это выполняет поиск подстроки, вы должны сначала конвертировать vowels в set). Чтобы сделать lambda, мы просто напишем: lambda letter: letter in vowels. (Мы можем использовать любые имена переменных мы, как здесь: это то же самое, как написание функции.)

  • дали письмо, перевести его в 1 если это гласный и 0 иначе. Фактически, результат letter in vowels будет работать так же хорошо, потому что он возвращает True или False, и они могут использоваться как числовые значения 1 и 0 соответственно. В зависимости от того, как вы интерпретируете аксиому Python explicit is better than implicit, вместо этого вы можете вместо этого написать int(letter in vowels) или даже 1 if letter in vowels else 0. Для того, чтобы сократить на ряде примеров, я буду просто использовать letter in vowels, даже если в моем собственном коде я люблю что последний :)

Кроме того, давайте упрощать. Как я уже отмечал ранее, наш vowels должен быть set. Я покажу, что только один раз, здесь: vowels = set("AEIOUaeiou"). Функции, показанные ниже, естественно, предполагают, что это глобальный;) Наконец, обратите внимание: нет причин для обработки пустой строки по-другому. Вы можете отлично перебирать пустую строку, не находить элементов, суммировать их до 0, находить ее длину равной 0 и т. Д. Она вообще не изменяет логику. Special cases aren't special enough.


Вперед до полного кода.

Мы можем делать то, что вы хотели сделать, а именно: включать элементы, которые являются гласными, и не выполнять преобразование - определить результат по длине полученного списка гласных.

def vowels_by_filter(string): 
    return len(filter(lambda letter: letter in vowels, string)) 

def vowels_by_filter_expression(string): 
    return len(letter for letter in string if letter in vowels) 

Или мы можем преобразовать все буквы в 1 или 0 (то есть, «число гласных», что каждая буква содержит), и сложить результаты:

def vowels_by_map(string): 
    return sum(map(lambda letter: letter in vowels, string)) 

def vowels_by_map_expression(string): 
    return sum(letter in vowels for letter in string) 

Или мы можем объединить эти подходы - включают только элементы, которые являются гласными, а затем преобразуют их в 1 (поскольку все, что мы включаем, является гласным, оно должно преобразовываться в 1, и нам не нужно снова проверять значение):

def vowels_by_both(string): 
    return sum(map(lambda letter: 1, filter(lambda letter: letter in vowels, string))) 

def vowels_by_full_expression(string): 
    return sum(1 for letter in string if letter in vowels) 

Эквивалентность в каждой паре должна быть достаточно очевидной. С выражением генератора (или пониманием списка) часть до for является нашей map, а часть в конце после if (если включена) является нашим filter. Нам всегда приходится писать «карту» с ними (даже если преобразование эквивалентно lambda x: x), но это избавляет нас от необходимости писать полный синтаксис lambda, и мы используем ту же свободную переменную как для «карты», и «фильтр», если он присутствует (т. е. наша итерационная переменная, letter в for letter in string).

3

Вы можете просто использовать выражение генератора и обеспечить его sum(), чтобы получить число гласных звуков, пример -

>>> def numVowels(s): 
...  vowels= "AEIOUaeiou" 
...  return sum(1 for x in s if x in vowels) 
... 
>>> numVowels("abcdefa") 
3 
>>> numVowels("") 
0 
>>> numVowels("bcdfgh") 
0 
+2

это звучит так, как цель этого excersize - практиковать lambdas: P, но да, вот как вы должны выполнить задачу без требования lambdas. –

+1

Угадайте, что этот ответ получил downvoted, потому что это не помогает OP с его домашней работой. –

+0

может быть ... Я, конечно, не делал это без изменений, так как это «правильный» способ сделать это ... или, по крайней мере, способ (я бы сделал «sum (x в гласных для x в s)» ... но yes: P –

3
vowels = "aeiou" 

count_vowels = lambda s: 0 if not s else ((s[0].lower() in vowels) + count_vowels(s[1:])) 

>>> count_vowels("hello world") 
3 

может быть?

0

Ваш код удален.

Как @acushner сказал, что суммирование строки не имеет смысла, поскольку Python начинает с 0 по умолчанию и ломается, поскольку вы не можете суммировать целое число и строку. (К счастью, сильная типизация позволяет нам исправить ошибки при разработке)

Также предположим, что работающая лямбда-функция работала, sum вернет целое число, то же самое каждый раз, и вы будете фильтровать на этом. Результатом может быть либо полная строка, либо ничего.

3

Используя свой собственный код, вам нужно фильтровать символы не гласные, вы можете опустить каждый символ и сделать гласными набор для O (1) операций поиска:

def numVowels(s): 
    vowels = {"a","e","i","o","u"} 
    if s == '': 
     return 0 
    else: 
     totalVowels = list(filter(lambda x: x.lower() in vowels , s)) 
     return len(totalVowels) 

который может просто стать:

def numVowels(s): 
    vowels = {"a","e","i","o","u"} 
    return len(list(filter(lambda x: x.lower() in vowels , s))) 

каждый x в лямбда является каждый символ из s, проходя lambda x: x.lower() in vowels фильтровать будет фильтровать любой символ из s, что не в наших гласных звуков, установленных таким образом, мы остались со списком просто не-vowles.

Вы можете комбинировать sum с filter и lambda:

def numVowels(s): 
    vowels= {"a","e","i","o","u"} 
    return sum(1 for _ in filter(lambda x: x.lower() in vowels , s)) 

или вообще когда лямбда не был nesessity, просто вернув выражение генератора будет лучшим подходом:

def numVowels(s): 
    vowels= {"a","e","i","o","u"} 
    return sum(x.lower() in vowels for x in s)) 

последняя часть ответа наиболее эффективна для больших входных данных, так как для наборов есть O(1). x.lower() in vowels будет либо True/False1, либо 0, поэтому вам просто нужно суммировать их все. Если s пустая строка или нет гласные sum возвратит 0

пример того, как x.lower() in vowels работ:

In [8]: tests = "String with vowels" 

In [9]: l = [x.lower() in vowels for x in tests] 

In [10]: l 
Out[10]: # list of booleans 
[False, 
False, 
False, 
True, 
False, 
False, 
False, 
False, 
True, 
False, 
False, 
False, 
False, 
True, 
False, 
True, 
False, 
False] 

In [11]: l = [int(b) for b in l] 

In [12]: l # list of 1's and 0's equating to True and False 
Out[12]: [0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0] 
+1

Использование 'filter', как это больно .. Кроме того, логика 'if ... else' бесполезна ...' len' вернет 0 в пустую строку. Также '((...))' – JBernardo

+1

@JBernardo, я использовал собственный код OP, показывающий им, как сделайте это с помощью своего кода, я также предоставил более эффективные способы, чем любой другой ответ, чтобы сделать это. –

+1

Для compl Вы могли бы также показать подходы, когда список не фильтруется, но гласные переводятся на «1», а негласные - на «0»? В остальном это отличный ответ. –

0

Есть много способов решить проблему подсчета количества гласных звуков в слове , но просто глядя на исправление кода:

totalVowels = list(filter(lambda c: c in vowels, s)) 
print(len(totalVowels)) 

Теперь отобразится количество гласных.
Похоже, вы действительно не понимали, как работает filter(), предложите перечитать документацию.

-1

Есть много ответов, и здесь мой ответ не является оптимальным, но я выложу его как «еще один вариант». Вы можете использовать метод reduce. Но этот метод не рекомендуется использовать, а в Pyton 3 он скрыт в модуле functools от встроенного.

from functools import reduce # in Python 3 

def numVowels(str): 
    return reduce(lambda acc, ch: x+1 if ch in 'AEIOUaeiou' else acc, str, 0) 

print numVowels('abc')