Найти - Пользователи
Полная версия: Синтакс функции max()
Начало » Python для новичков » Синтакс функции max()
1 2
EvgenKlim
Доброго времени суток!

Недавно разбирал задачу определения наиболее встречающейся в тексте буквы и наткнулся на решение:

import string
 
def checkio(text):
    """
    We iterate through latyn alphabet and count each letter in the text.
    Then 'max' selects the most frequent letter.
    For the case when we have several equal letter,
    'max' selects the first from they.
    """
    text = text.lower()
    return max(string.ascii_lowercase, key=text.count)

Понятно, что функция сравнивает неск аргументов и выбирает максимальное из них. Но по факту - как используется key? Смотрел много примеров, везде по разному, единого правила не нашел. В интернете нет описания этой функции, кроме стандартного, в котором ничего про key не сказано.

В данном случае получается мы сравниваем алфавит ‘abcdef…xyz’ с текстом # “Lorem ipsum dolor sit amet”. Т.е. первый аргумент - алфавит, 2й - буква в тексте. Хотя опять же непонятно как здесь сравнение идет побуквенно и непонятна запись “key=text.count”. У функции Count другой вобще синтаксис - Count(что считать). Но здесь text.count все по-другому.

И, допустим сравниваем алфавит с 5 буквами ‘a’(посчитал Count). В данном случае почему выберется максимальное ‘a’?
Вобщем не могу понять как работает это решение, а оно работает.

Помогите пожалуйста разобраться.
doza_and
как это нет информации?
>>> print max.__doc__
max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.
>>> 
key это функция которая по объекту возвращает значение которое подлежит сравнению.
EvgenKlim
doza_and,

Непонятно что возвращает text.count, и почему без скобок написана? и как в данном случае сравнение идет с алфавитом? т.е. посимвольно?
JOHN_16
EvgenKlim
без скобок потому что передается именно объект функции,а не результат ее выполнения. Функция max будет внутри себя вызывать передаваемую функцию.
Например
a=range(5)
b=range(10,15)
c=range(5,10)
print max(a,b,c, key=lambda x: x[1])
результат:
[10, 11, 12, 13, 14]
Здесь функция max принимает на входе 3 списка, а с помощью key мы определяем функцию (анонимная=лямбда) которая заставляет max сравнивать списки по второму элементу каждого из них.
EvgenKlim
JOHN_16,

в Вашем примере все понятно.

в данном случае “max(string.ascii_lowercase, key=text.count)” здесь один аргумент - строка текста ‘abcd…xyz’, другой - функция text.count, причем text - это строка, а у строки нет метода Count, он есть у списков. и что возвращает эта функция text.count непонятно…

Можете посоветовать какуюн хорошую книгу или сайт где можно ознакомиться с функцией max()?
mgk
Для примера, как работает count:
>>> 'aabccc'.count('a')
2
>>> 'aabccc'.count('b')
1
>>> 'aabccc'.count('c')
3

Дальше. Разбираем строку:
max(string.ascii_lowercase, key=text.count)
1. Для каждого элемента из string.ascii_lowercase, т.е. для каждой латинской буквы, будет вызываться функция, которая указана в параметре key, т.е.
text.count('a'), text.count('b'), ..., text.count('z')
.
2. Из тех значений, которые возвращает функция text.count для каждой буквы уже и ищется максимальное значение.
Вот и получается, что функция в итоге возвращает наибольшее количество вхождения одной буквы из всего латинского алфавита.
EvgenKlim
mgk,
Спасибо!!!!

Спасибо всем за помощь!!!
py.user.next
EvgenKlim
text - это строка, а у строки нет метода Count, он есть у списков
Вот это главное заблуждение, у строки есть метод .count()
dir('')

EvgenKlim
Недавно разбирал задачу определения наиболее встречающейся в тексте буквы и наткнулся на решение:
А само решение не хорошее, ввиду того что при каждом .count() он будет проходить всю строку. Получается, если в строке миллион символов, он будет миллион раз проходить по миллиону символов.
EvgenKlim
py.user.next
наверно я неправильно записывал, что ошибка появлялась.

а как еще можно определить частоту буквы? в любом случае придется проходить всю строку.
я лично делал через Counter, но это еще дольше. Сортировка нужна, т.к. если например слово “bca”, то ответ = ‘a’, т.е. при равной частоте вывод по алфавиту

import re
from collections import Counter
s="One"
st=re.compile('[a-zA-Z]')
def checkio(text):
    ns=""
    for i in text:
        if st.match(i): ns+=i
    ns=ns.lower()
    ns=list(ns)
    ns.sort()
    d=Counter(ns).most_common(1)
    return d[0][0]

видел также такое решение
return max(set(text), key=text.count)

предварительно text очистили от небукв.
JOHN_16
EvgenKlim
предварительно text очистили от небукв.
глубоко заблуждаетесь, set это множества, вот вам для примера:
>>> set('aaabcbc')
set(['a', 'c', 'b'])
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB