Ерунда на itertools и генераторах
Я люблю itertools и генераторы в Пайтоне,
Прочитал тут на «Хабре», что дробь 1/998001 даёт последовательность из чисел от нуля до 997. Вот я и написал код с использованием генераторов и itertools, который берёт эту дробь и выводит из неё все числа последовательно, пока не попадутся числа с разницей не равной единице.
from decimal import Decimal, getcontext
from itertools import groupby, islice, izip, takewhile, chain, imap
getcontext().prec = 3000
n = (
groupby(
enumerate(
islice(str(1 / Decimal(998001)), 2, None)
),
lambda n: n[0] // 3)
)
n = (int(''.join(n[1] for n in n[1])) for n in n)
n = chain(*takewhile(lambda n: n[1] - n[0] == 1, izip(n, n)))
print ', '.join(imap(str, n))Кстати, для вычисления дроби с точностью до трёхтысячного знака, используется модуль decimal.
Подумалось, что многим, наверное, было интересно сравнить как выглядит эквивалентный код на Пайтоне без всех этих страшных (на взгляд большинства) ленивых выражений. А то некоторые ребята по моей вине уже думают, что Пайтон
from decimal import Decimal, getcontext
getcontext().prec = 3000
number, prev, out = str(1 / Decimal(998001)), -1, []
for i in xrange(2, len(number), 3):
curr = int(number[i:i+3])
if curr - prev != 1: break
prev = curr
out.append(str(curr))
print ', '.join(out)
Комментарии 17
А я теперь определиться не могу как мне больше нравится, а это значит что PEP20 всё врёт
А зачем лаконичный код 2 листинга превращать в «не такой очевидный» код 1 листинга.
К тому же нет выигрыша ни по
Есть выигрыш по скорости и простоте модификации, кстати, но для этого нужно уметь это читать, конечно.
Ну вот
А вот про Python тут
Кстати, а почему у вас в блоге время не в моём часовом поясе, и это никак не обозначено?
Комментарий для profiles.google.com/jankkhvej/:
Процессоры — нет.Процессоры-то тут причём? Это всё равно раскрывается в обычные циклы с условиями, процессорам всё равно какие там конструкции.
Я дажекак-то теряюсь перед вашим вопросом. Наверное потому что это мой блог?
Комментарий для Евгения Степанищева:
из-за названий переменных, например:
Мне сложно читать первый пример
Почему тут все n? :) В остальных строках кода, кстати, тоже. Во втором примере они хоть и сокращенные, но можно предположить по названиям, что они означают.
Ну, сначала там не «n» были, это уже для запутывания :)
Я как то ожидал, что если я его читаю :), то время должно отображается в они часовом поясе. Тем более, что везде практически так и происходит.
Насчёт того, что неважно, какой процессор — ну как же ж?! А кто будет исполнять
Комментарий для profiles.google.com/jankkhvej/:
Где, например?
Процессор. Я же написал — эти конструкции всё одно будут развёрнуты в циклы и условия. Всё равно процессору что там за конструкции. Вопрос, наверное, в том насколько эффективно будут развёрнуты. Но тут вопрос реализации, сами по себе конструкциикаких-то ограничений в этом смысле не несут.
Комментарий для Евгения Степанищева:
что-то наподобие:
Кстати, использование ленивых выражений вовсе не обязывает к написанию диких однострочников. Вполне можно писать
Ну и так далее. В сочетании с несокращенными названиями переменных получается, на мой взгляд, гораздо понятнее.
Как будто цель в понятности. Первый абзац же раскрывает тему :)
Ну и использование промежуточных переменных всё ломает, так как, попытайся я встроить
Комментарий для Евгения Степанищева:
Не очень понял. Если вставитьчто-то в цепочку в твоем примере, то придется (в общем случае) все равно переписывать то, что идет выше уровнем, потому что данные просто другие будут. В моем случае — в тех строчках, где данные другие, ты все равно будешь менять правую часть, ну и заодно переменные переименуешь. А с того момента, когда данные становятся такими же, все останется прежним.
Это уже другая задача, я опять не вижу связи с ленивыми выражениями. Вот ты не боишься, что у тебя во втором коде «prev»где-то ниже будет использоваться? Вообще, если название переменной описывает ее содержание (у меня не совсем так, «grouped_digits» используется два раза, но мне было лень думать, как назвать дополнительную переменную), то вероятность двойного использования переменной снизится. Также снизится и от разделения кода на независимые функции.
Комментарий для Евгения Степанищева:
Я про это и спрашивал. Наверное,как-то не очевидно. Ну да ладно, погуглю ещё сам, спасибо за интересную тему.
Ты, Володь, рушишь всю идею, вот я и сопротивляюсь :) Написать