Pull to refresh

Comments 83

> к которой можно отнести и создание новых списков, и модификацию существующих.
Как, используя list comprehension, модифицировать существующий список?
думаю что никак.
хотя в питоне и можно при генерации модифицировать исходный список, но новый всё равно создаётся.
От условия в цикле можно избавиться используя defaultdict(int).
Еще можно красиво посчитать суммарный трафик:
print "Total traffic: %d bytes" % sum (bytes for (ip, bytes) in lst)
спасибо, вы мне подсказываете поле дял будущей деятельности далеко вперед :)
Так и называется, потому что создается генератор элементов :)
Генераторы вообще отличная штука.
и итераторы, и декораторы и многое другое :)
List comprehension - это и есть генератор, пропущеный через функцию list() путём помещения в квадратные скобки. А вот если всё так не упрощать, можно получить всякие замечательные штуки, например, объект, генерирующий бесконечную последовательность, элемент за элементом.
Понятно, конечно, что xrange в первом примере статьи использовался как пример к последующему материалу, но применение range для создания списка нечетных числе выглядит более очевидным, да и работает быстрее. Впрочем, в Python 3000, если не ошибаюсь, range приобретет поведение xrange, а последний исчезнет.

Спасибо за статьи!
Вызов метода происходит дольше. И вообще, метод has_key, вроде, устаревшим уже считается.
именно. :) мне пришлось переучиваться.
кстати, open вроде тоже depricated... надо пользовать file.
По крайней мере для 2.5 документация рекомендует для открытия файлов использовать именно open, а file оставить как тип. Поменялось ли что-то по этому поводу в 3.0, не помню.
То, что file новее open и идентичен ему, не значит, что старая функция стала deprecated. Раздел built-in functions рекомендует семантическое разделение, которое я полностью поддерживаю.
ну не от скуки ж ее объявили "оставленной для совместимости" :)
Где именно?
Кстати, я сейчас быстренько собрал 3.0b2, и там file даже нет в built-ins, в отличие от open.
file() is new in Python 2.2. The older built-in open() is an alias for file().
ну да, в принципе это не deprecation. но меня слово older настраивает на минорный лад
for line in file читается лучше, чем for line in open.
Это уже субъективизм полнейший.
Я обычно пишу for line in some_file и some_file закрываю явно или с помощью with ... as
UFO landed and left these words here
"list comprehensions" часто переводят, как "генераторы списков"
фак май брайн!
А питон, я на него смогу перейти с php?
разумеется перейдешь) я с нуля питон осознал за 30 минут.. :) До этого вообще ни на чем не программил :) Отличный язык)
Ну ты меня успокойил, может у мну моск не столько функционален как твой))
попробуем
так ты можешь все это не использовать пока. Пайтон не Хаскелл. в нем ФП - приятное дополнение, а не необходимость. пока можешь писать императивно, а потом использовать все что хочется :)
Ну, те же генераторы — это уж отголоски ленивых вычислений. Так что потихоньку различия стираются. :)
Перейти с PHP на Python легко, а вот обратно сложновато. Потому что не хочется. :)
в точку. не могу использовать РНР хотя и пытался :(
питон на то и питон, задушил?? ))))
Да бросьте. Вполне нормально использую оба языка. Никаких проблем не заметил :)
Раз уж проскочила lamda, дальше лучше про функциональное программирование. За статьи спасибо. Давно хотел почитать, но было лень, а тут все готовое :)
Спасибо за статью. Примеры достаточно интересные, вроде бы и раньше про это знал, однако на практике часто забываю.
"# 2 заполняем словарь" можно чуток сократить
rmp = {}
for ip, traffic in raw:
rmp[ip] = rmp.get(ip, 0) + int(traffic)
можно. я пытался не запутать все совсем окончательно :)
from collections import defaultdict
rmp = defaultdict(int)
for ip, bytes in raw:
rmp[ip] += int(bytes)

Так гораздо приятнее, по-моему :)
вариант не мой, но внушает :)
l = (lambda f:
(lambda l: l.sort(reverse = True, key = lambda (k, v): v) or l)(
(lambda m, f:
filter(
lambda (i, t):
m.__setitem__(i, m.get(i, 0) + int(t)),
[j.split(' ') for j in file(f, 'r').readlines()]
) or m.items()
)({}, f)
)
)('in.txt')

print '\n'.join('%s = %d' % (i, t) for (i, t) in l)


свернуть по вкусу.
тут примеры покруче ;-)
http://ru.wikipedia.org/wiki/Brainfuck
руки б за такие "варианты" поотрывал...
lftltltllormjijk - может еще так начнем писать?;)
это - всего лишь концепт. для демонстрации идеи что всем можно довести до безумия :)
на счет дельнеших уроков - я за ООП.. ибо питон сам по себе ООП язык - он на это больше их ориентирован
Присоединяюсь! Хотелось бы почитать о «new-style» классах.
class MyClass:
# old-style class
pass

class MyClass(object):
# new-style class
pass

Как-то так (:
ага, только еше super, mro и метапрограммирование.
ага, только еще super, mro и метапрограммирование.
Может быть, ты тоже что-нибудь о python напишешь? Хотя бы в личный блог.
Например о том же мета-программировании, с практическими примерами и домашним заданием.
Ну, это-то я знаю... Хотелось бы почитать про идеологические различия и про то, почему в Python 3000 все классы станут «new-style».
Раз уш использовали xrange то и вместо for name, salary in dic.items() лучше for name, salary in dic.iteritems() :)

А вообще спасибо) давайте продолжим ООП?)
Вы бы добавили про разницу range и xrange...
range создает список, а затем по нему проходит. Если список очень большой, то он будет жить в памяти и сожрет много ресурсов.
xrange возвращает "xrange object". Каждый элемент поочередно создается и передается, затем память освобождается.

Например, x = range(0,10) создаст list и передаст его переменной x.
>>> print x
[1, 2, 3, 4, 5, 6, 7, 8, 9]

С xrange такой фокус не прокатит:
>>> x = xrange(0,10)
>>> print x
xrange(10)
Сейчас специально слазил - там нет ни слова про xrange :)
прошу прощения, мой косяк. мне упорно казалось что это я объяснил :(
Кстати в python 3000 range будет ленивым, т.е. вместо range будет xrange. Ленивыми также будут map/filter и т.д.
Спасибо, очень интересно и практично. Не оторвано от реально жизни...
Как по мне, так ООП и так мейн стрим, найти инфу, что про него, что про ООП в питоне ю не так уж и сложно.
А вот с функциональным, все гораздо печальней. Найти материал, для чего функциональное программирование может быть полезным, не математику да еще и в питоне, не такто легко.
Так что обеими руками за функциональное программирование.
Спасибо за ссылку! Кажется даже читал в свое время :)
Но опять же, даже эта статья не дает простых, чётких примеров. Она интригует и манит, обещая невероятные чудеса... но не показывает их :)
Хотя думаю на деле все проще, и разница примерно как между Windows vs Linux. Фанаты спорят до хрипоты, а разумные так или иначе используют и то и другое. :)
Поэтому очень хочется увидеть в примерах, как это может упростит наш тяжелы, бессмысленный труд :)

PS - чую, что как человеку разрабатывающему на JavaScript, многие вещи окажутся очень знакомыми. Я же правильно понимаю, что анонимные ф-ции, замыкания и map reduce это все из ф-циональной оперы?
в общем - по всем пунктам вы правы. даже и добавить нечего :)
нет, функции высшего порядка, замыкания и свёртки не являются прерогативой фп. лексические замыкания, например, появились первыми в императивных языках, потом их подхватили функциональные, потом императивные позаимствовали у функциональных функции высшего порядка и свёртки.
точнее сказать, свёртки можно было создавать на императивных языках и раньше, но в этом небыло особого смысла ввиду отсутствия функций высшего порядка.
возможно. не могу спорить, но мне этот термин почему-то кажется каким-то громоздким и непонятным. ъотя омжет я не прав.
Общепринятого перевода нет, насколько я знаю, даже для соответствующего теоретико-множественного понятия, от которого и пошёл английский термин. Все равно тащить математические истоки не получится, ZF-нотация будет звучать совсем дико. Списковые включения, списковые выделения…
>print "\n".join(["%s = %d" % (name, salary) for name, salary in dic.items()])
моожно так print "\n".join("%s = %d" % (name, salary) for name, salary in dic.items())
Ваш вариант генерит список и он отдаётся дойну, второй вариант создаёт генератор на пододе xrange.
А вообще продолжайте в том же духе, пусть народ пишет на питон "правильно" :)
у меня цель была - продемонстрировать list comprehensions в работе.
если захотеть, можно этот пример в однострочник свернуть, но смысл?
if ip in rmp: rmp[ip] += int(traffic)
else: rmp[ip] = int(traffic)

ужос. так нельзя?

if ip in rmp: rmp[ip] = ( rmp[ip] || 0 ) + int(traffic)
А на хабре никак нельзя использовать подсветку кода? Ну или хотя бы форматирование что бы сохраняло - удобнее читать. А то через строчку - неудобно, да и преимущество форматирования табами - не так заметно.
Ну и стоило сказать,что не надо увлекаться подобного рода сахаром в явный ужерб читабельности :)
подсветку - только сторонними "раскрашивалками". для пайтона я пока не нашел подходящей.
а большие интервалы между строками - "фича" работы тега pre
Ядумаю, любая из популярных подойдёт. Не понравится - замените.
Всё лучше чем плейн-текстом. Эта "фича" - сильно глаз режет.
честно. я нашел парочку, но они дают хабронесовместимый код. так что я не знаю пока что делать...
Скажите, а продолжение будет?
И не подскажите где можно найти разнообразных задачек?
продолжение, надеюсь будет… когда будет время :(
а задачки — попробуйте Python Challenge — там их дико много…
спасибо за хороший цикл статей, надеюсь, что напишите-таки продолжение.

и просьба-совет — было бы очень удобно, если бы в начале давались ссылки на остальные статьи этого цикла.
Действительно отличный цикл статей для людей, который вообще с пайтоном не знакомы (как я :)).
Но последний пример можно реализовать в 8 строк читаемого кода на PHP (в примере я насчитал 10):
$lines = file( 'ip.log' );
$data = array();
foreach( $lines as $line ) {
$lineData = explode( ' ', $line );
$data[ $lineData[0] ] = isset( $lineData[0] )? $data[ $lineData[0] ] + $lineData[1]: 0;
}
arsort( $data );
var_dump( $data );
В будущем, хотелось бы почитать об ООП в пайтоне, и если можно, сравните реализацию ООП с PHP
если поставить за цель — в пайтоне можно строки в 4-5 уложиться. но сильно в ущерб читабельности это ж просто учебный пример.
Only those users with full accounts are able to leave comments. Log in, please.