All streams
Search
Write a publication
Pull to refresh
30
0
Алексей Пирогов @Astynax

Пользователь

Send message
Можно и так. Но перегрузка операторов имеет одно неприятное свойство: не всегда прогнозируемый порядок вызова, а это как раз минус: в монадном контексте порядок вычисления должен быть строго последовательным.
Я тоже сначала сделал перегрузку >>, |, *, и вот тут то меня и подвел приоритет операций. В вашем варианте перегружен только пайп, но даже он уже может быть как лево-, так и правосторонним.
А вот за это спасибо большое! Единственно, неудобно узнавать кол-во параметров у метода — self тоже считается.
Каррированная функция нескольких параметров представляет собой функцию одного параметра, возвращающую функцию одного параметра, возвращающую функцию одного параметра… Самая глубоко вложенная функция принимает последний параметр и возвращает результат.

При частичном применении можно задать какие-либо параметры, не обязательно первые, и в итоге получится функция от оставшихся параметров, которая опять может быть частично применена, а может и не быть.
Спасибо большое за информацию. Похоже key вычисляется один на элемент в первом проходе, а далее сортировка одних лишь ключей происходит, а cmp вызывается многократно для каждого конкретного элемента при сравнении его с другими.
Не знал, спасибо большое за информацию. Как раз подумывал замеры провести. Похоже key вычисляется один на элемент в первом проходе, а далее сортировка одних лишь ключей происходит, а cmp вызывается многократно для каждого конкретного элемента при сравнении его с другими.
Так и приходится:
key = lambda obj: (obj.age, -obj.iq, obj.weight)
Отлично, скоро будет статья.
Тут сказывается замороженный синтаксис Python — ничего нового не добавишь, только перегрузка и остается ))
А в вашем примере можно и не перегружать пайп, даже читабельнее будет:
def push_through(*funcs):
    def inner(value):
        return reduce(lambda x, f: f(x), funcs, value)
    return inner

print ','.join(map(push_through(int, str), [4.5, 6.7, 8.02]))

Только тут функции идут в порядке их применения, а не в обратном порядке, как в композиции. Здесь происходит «проталкивание» данных через последовательность обработчиков. Порядок применения функций, само собой, можно и развернуть.
О, получилось!
. . .
>>> sorted(l, cmp=lambda x, y: 0 if sign(x) == sign(y) else cmp(x, y))
[-10, -9, -5, -1, -7, -3, -4, -8, -6, -2, 0, 7, 8, 3, 4, 6, 2, 9, 5, 1]
Есть у моего способа сортировки папа преимуществ:
1) если для сравниваемых пар вторые элементы уже позволяют определить порядок, первые не будут сравниваться, В варианте с key, ключ-пара будет создаваться в любом случае.
2) получение ключа каждый раз, это создание/«уборка» нового объекта, поэтому накладные расходы всё равно будут.
самое интересное, что два ключа внутри sort/sorted, скорее всего, все равно «скармливаются» функции cmp — она определяет порядок следования элементов ))
Придумал пример, немного синтетический, правда, того случая, когда cmp не применишь, по крайней мере в лоб.
Задача: нужно распределить числа в массиве по группам отрицательные, ноль(ноли) и положительные.
key вполне работает.
>>> import random
>>> l = [x - 10 for x in xrange(20)]
>>> random.shuffle(l)
>>> l
[7, 8, -10, -9, 3, 0, 4, -5, -1, 6, -7, -3, -4, -8, 2, 9, -6, -2, 5, 1]
>>> sign = lambda x: -1 if x < 0 else (0 if x == 0 else 1)
>>> sorted(l, key=sign)
[-10, -9, -5, -1, -7, -3, -4, -8, -6, -2, 0, 7, 8, 3, 4, 6, 2, 9, 5, 1]

Причем порядок чисел внутри групп не поменялся!
Интересно? Могу написать последовательно, начиная с функторов, с примерами. Есть желание адаптировать «Learn you a Haskell for great Good», уже в Python-ключе и для императивщиков
На самом деле, ИМХО, key vs cmp — дело вкуса, ни один вариант не сложнее понимать, при наличии, собственно, понимания принципов работы сортировки.
Особенно, примеры и последовательность подачи материала удачны.
Последовательность: Maybe, IO (как magic-штуки в конкретных задачах) -> функторы -> аппликативные функторы -> монады. В процессе подачи материала та же Maybe сама вырисовывается и пишется с нуля: вот тут то и приходит понимание
Тут вы правы. Скорректировал. В данном случае именно частичное применение, с замыканием части параметров и возвратом функции, принимающей оставшиеся. Каррирование (нормальное) в Python страшновато выглядит.
Стандартное поведение при сравнении списков/кортежей:
(a1, b1) > (a2, b2) если a1 > a2, или b1 > b2 при a1 = a2
[::-1] разворачивает пары задом-наперед, чтобы сравнивались сначала вторые элементы
У key и cmp смысл разный: cmp позволяет нам сравнивать элементы, в то время как key дает нам возможность предоставить ключ для сортировки. Первый случай гибче, но не так часто нужен.
Иногда удобно использовать не key, а cmp.
К примеру, нужно сортировать список пар сначала по второму элементу:
>>> l = [(1, 2), (4, 5), (100, 1)]
>>> l.sort(cmp=lambda (x1, y1), (x2, y2): cmp(y1, y2) or cmp(x1, x2))
>>> l
[(100, 1), (1, 2), (4, 5)]

ИМХО, весьма наглядно: для сравнения (cmp) пар, нужно сравнить (cmp) вторые элементы, а потом сравнить (cmp) первые.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity