Pull to refresh

Comments 67

«Считаете, что прочитать о нескольких уловках лучше, чем провести остаток жизни за чтением документации?» — в принципе в документации написано про это…
Да, но документация длинная, и прочитать ее целиком довольно сложно.
Осилить документацию не сложно, сложно найти и запомнить такие полезные плюшечки.
D целом при использовании данный советов код становится более человеко-читаемым. Это есть хорошо, я считаю.
Спасибо! Очень познавательно и понятно объяснено.
Очень понравилось, что в довольно сжатой форме показаны конструкции которые привычны для Python'а но не привычны для других языков. У многих новичков с ними проблемы.
Спасибо. Уже видел где-то генераторы списков, но когда приходило время использовать — никак не мог вспомнить синтаксис.
Опа, а про «if substring in string» не знал. Спасибо!
UFO just landed and posted this here
UFO just landed and posted this here
Странно, что использование map или filter вызовает вопросы у «человека, незнакомого с Python». Функции стандартные, практически азы.
Функции стандартные, но лучше бы они были методами списка и кортежа. Чтоб писать что-то типа
ints=[1,2,3,4,5]
ints.filter(lambda x:x
то есть
ints=[1,2,3,4,5]
ints.filter(lambda x:x<3).map(lambda x:x+3)
в ruby так:
ints.reject {|e| e < 3}.map {|e| e+3}
Нельзя. Потому что аргументами map и filter может быть любая итерируемая последовательность (sequence), а не только список и кортеж. А таких последовательностей ой много. Строка, к слову, тоже последовательность (букв). И словарь — последовательность (ключей).
А в чем проблема? Метод map может существовать у всех итерируемых объектов (если не ошибаюсь, так и есть в Ruby).
А проблема в экспоненциальном взрыве.

В любом случае, если язык позволяет делать map(… any_sequence), и если язык позволяет делать any_sequence.map(...), где any_sequence — это действительно любая последовательность, с которой функция map заранее незнакома (например, реализующая метод __iter__, как в Python-е, или унаследованная от какого-то абстрактного класса ISequence, как даже не знаю где — а как, кстати, в Ruby? емнип, там новые подобные функции можно сразу привязать ко всему встроенному классу sequence-а), то с функциональной точки зрения любые подобные языки эквивалентны. И выбор дальше — уже дело вкуса.
Относительно ruby: читайте коммент ниже + достаточно реализации методов each и << (если ничего не путаю) у постороннего класса.
Ошибаетесь. В Ruby есть модуль Enumerable, который подмешивается ко всем «итерируемым» классам и map определен в нем, а уже он подмешивается в другие классы. Например в 1.8 он подмешивается к String, а в 1.9 уже нет. Таким образом всегда можно написать свой класс, и подмешав в него Enumerable сделать доступным для него кучу фишек, таких как map, sort…
дак ну и свои итераторы делаются за пару секунд…
В первом выражении используется X
squares = map(lambda x: x*x, numbers)
А во втором number. Лучше будет в едином стиле ( с иксом, имхо, еще красивее )
squares = [x*x for x in [1,2,3,4,5]]
Спасибо за статью. Незнавшим может помочь.
Четыре типа кавычек.

Вообще говоря, их пять. Ещё есть обратные кавычки:
from decimal import Decimal
print `Decimal(1) / 3`
Но лучше бы их не было, конечно. И в Python 3.x их уже нет.
А чем они плохи? Поясните начинающему, пожалуйста.
Ну, функция repr() же есть. И она именно функция, сущность обычного и уже имеющегося типа. Совершенно новую сущность — «строки с обратными скобками, которые, на самом деле, даже и не строки совсем, а просто применение функции repr() к аргументу» (да-да, это настолько не строки, что `a\nb` они даже не поймут) вводить совершенно не обязательно. И только собьёт с толку, заставив думать, что обратные кавычки в Python имеют хоть какое-то отношение к обратным кавычкам в Perl/Shell (которые подразумевают, что их аргумент запускается в шелле, и возвращают вывод запустившейся программы).
Не очень понял как это используется? Типа inline-eval?
Кто ещё думает, что язык укурошный? И кому он за это нравится?
Прежде чем говорить об укурошности Питона, посмотрите на язык Ruby и почитайте книжку Why's (poignant) Guide to Ruby.
Chunky beacon, chunky beacon!
Замечательная книжка, замечательный язык. «Укурошный» ровно настолько же, насколько и Питон.
Книжка волшебна, язык прекрасен, я был в него просто влюблён в своё время.
Дополнительный бонус: join работает линейное время. Никогда не создавайте строку складыванием элементов списка в цикле for: это не просто некрасиво, это занимает квадратичное время!


Кстати, про «квадратичное время» — чушь. Уже достаточно давно складывание элементов не вызывает переаллокаций памяти, и, соответственно, не занимает квадратичное время.

Впрочем, это нисколько не мешает складыванию элементов в тех случаях, когда можно использовать join, выглядеть уродски.
Мне это тоже показалось подозрительным. Но спорить с автором статьи — не моя задача.
Лямбда-функции

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


А преимущество Python-а в том, что в нём огромное количество функций уже определено. Например, там, где можно использовать lambda a, b: a + b, там же можно использовать и operator.add.

а по-моему так наоборот, все эти

from operator import itemgetter
mylist.sort(key = itemgetter(1))

— то еще это уродство)

mylist.sort(key = lambda x: x[1]) — проще, понятнее, гибче, ничего импортировать и запоминать не нужно
itemgetter — ага, уродство. Но, говорят, чуточку более производительное. Только это его и оправдывает.
А готовые операторофункции типа add/sub уж точно понятнее лямбд.
«Говорят»? А что Вам мешает проверить?
Генератор списков


На самом деле, синтаксис list comprehension/generator expression чуточку богаче и позволяет, например, в одном генераторе использовать сразу несколько циклов и проверок, в т.ч. проверки между переменными цикла. Например,
[(x, y, x * y) for x in xrange(10) for y in xrange(10) if x < y]

Эти примеры в оригинале статьи тоже есть.
Просто переведена пока только первая часть.
www.siafoo.net/article/52
ничего нового.

это все будешь знать прочитав всего дайв инту питон — отправная точка любого питониста

лучше бы написали как получить все методы класа или типа того, а это имхо каждый школьнег знает
>> как получить все методы класcа
И об этом Пилгрим пишет в dive into python.
Вопрос к знающим.
Если весь список должен находиться в памяти при использовании генераторов списка, то как обстоят дела с генераторами словарей?
> Если весь список должен находиться в памяти при использовании генераторов списка

О каком списке идет речь? Если хотите получить список, то, понятное дело, он нужен в памяти, как его еще получить-то. Получить список (объект типа list) — это и значит «сформировать его в памяти», по определению.

Если хотите пройтись по каким-то объектам, то их список целиком в памяти держать совсем не обязательно. Для этого генераторы и придумали. Например, можно на генераторах сделать бесконечный «список», который в память бы не влез чисто теоретически.

Причем тут вообще словари — непонятно.

Думаю, когда сформулируете вопрос по-нормальному, то и ответ сразу сами найдете.
пункт 1.2:
в примере ошибка. у всех if'ов кроме первого в условии что-то делает object вместо my_object
2.1.2:
numbers = [1,2,3,4,5]
numbers_under_4 = filter(lambda x: x < 4, squares)
# numbers_under_4 = [1,2,3]

s/squares/numbers/
Спасибо, исправил. В оригинале эти ошибки тоже есть, и я их проглядел.
стоит сообщить о них автору, думаю
Да, я написал ему на почту.
#:"'("___[До_чего_же_все_-_таки_уродлив_этот_"'"__Питон__"'"!_!_!]___")'"();
в этапах освоения пайтона я, признаться, не разбираюсь, но в книжке по его азам — Learning Python by Mark Lutz обо всем этом сказано, к тому же используются правильные названия переменных: spam, eggs etc. слова хаки и уловки в заголовке излишни, imho.
«Генераторы списков» — это я полагаю то, что другие называют списковыми включениями?
Это то, что в документации называют list comprehensions.
>> [number*number for number in numbers if number < 4]

Ехал number через number, видит number в реке number, number, number, number, number…

Простите, не сдержался
Ехал = [ (number, через(number), видит (number)* в реке(number) ) for number in numbers if number*number ]
Раздел 1.5 безнадёжно устарел, он верен только для Питона 2.x.
Честно говоря, ни разу в продакшене не встречал Python 3k
2.x вполне себе продолжает развиваться, несмотря на существование 3.х.
Грядущая 2.7 положит конец развитию. Дальше только багфиксы.
хочется более подробной статьи про лямбда функции на русском, с доходчивым объяснением (например reduce)
Разве еще что то можно сказать о них? Кажется все и так уже ясно…
Было интересно прочитать статью со стороны знатока Ruby.
Мое удивление вызывает только функция join. Мы же join-им массив, а не строку? Может логичнее все таки массив.join(строка)?
join переводиться как «соединить», таким образом: массив.соеденить(строкой) мне кажется логичней, чем строку.соединить(массивом)
Наверное поздновато отвечать (через три года) но для потомков пригодится.
Дело в том, что соединять через join можно не только списки, но и любые другие итераторы, как встроенные (кортежи, генераторы), так и пользовательские. Отсюда получается, что удобнее иметь единственный метод в строке, чем реализовывать в каждом новом итераторе.
Sign up to leave a comment.

Articles

Change theme settings