Pull to refresh

Comments 51

Спасибо большое, некоторые вещи не знал. Например, тоже порадовал grouper. А некоторое помню ещё из книжки: обмен переменных местами, аргументы функции, перенос текста.
И немножко режет слух «пайтон». «Питон» как-то более по-русски чтоли…
Уж извините, название в честь Монти Пайтон… Вы же не называете её «Монти Питон»? :)
Do you how russians call our python? Peeeton.
Пример ленивой сортировки. heapq.heapify по месту делает из списка кучу за линейное время, а heapq.heappop извлекает за тем верхний элемент.
import heapq

def lazy_sort(iterable):
  lst = list(iterable)
  heapq.heapify(lst)
  while lst:
    yield heapq.heappop(lst)

print "".join([c for c in lazy_sort(u"абракадабра")])

Результат: аааааббдкрр
PS. Еще один пример ленивой генерации всех перестановок. Стандартная правда более универсальная.
def permutations(items):
  def p(items, n):
    if n == 0:
      yield []
    else:
      for i in range(n):
        for j in p(items[:i] + items[i+1:], n - 1):
          yield [items[i]] + j
  return p(items, len(items))

= 0
for i in permutations(range(10)):
  if k >= 5:
    break
  print i
  k += 1

Результат первые 5 элементов (всего их 10!=3628800):
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
[0, 1, 2, 3, 4, 5, 6, 8, 7, 9]
[0, 1, 2, 3, 4, 5, 6, 8, 9, 7]
[0, 1, 2, 3, 4, 5, 6, 9, 7, 8]
k = 0
for i in permutations(range(10)):
  if k >= 5:
    break
  print i
  k += 1

с itertools превратится в
list(islice(permutations(range(10)), 5))
Конечно так, проще. Я просто пример давал для понимания ленивых вычислений. Я реализация более общей permutations достаточно громоздкая.
Построение кучи (heapify) занимает время, выполняя по сути половину сортировки, так что не очень лениво получается.
А еще многие эти «неизвестности» есть в книге «Изучаем Питон».
Ну вот… Что же вы наделали… Сейчас HR-ы начитаются и начнут эту бесполезную муть (по большей части) на собеседованиях спрашивать…

А вообще интересно.

По поводу rot13 есть еще такой прикол: эту кодировку можно указывать в «магическом комментарии» кодировки python программы. Например вот работающая Python программа:

# -*- coding: rot13 -*-
vzcbeg urncd

qrs ynml_fbeg(vgrenoyr):
  yfg = yvfg(vgrenoyr)
  urncd.urncvsl(yfg)
  juvyr yfg:
    lvryq urncd.urnccbc(yfg)

cevag "".wbva([p sbe p va ynml_fbeg(h"dhrdjrdjr")])
Отлично сочетается с комбинацией клавиш в Виме: ggg?G
>> Поправить его можно просто и элегантно
и что элегантного тут?
Элегантность — довольно субъективное понятие. Если вариант решения, при котором создается отдельная функция make_lambdas(i), которая возвращает готовые lambd-ы, которые работают корректно (в этом случае уже используются замыкания).

А вобще я согласен, что пример немного надуманный. Добавлю ссылку на Execution model — возможно даже надуманный пример воодушевит кого-то на изучение доки.
Питон силён, во многом благодаря своей стандартной библиотеке. Но тока двойные for в z-конструкторах списков редко когда бывают к месту. Это и в документации отмечено, что чаще бывает проще и понятней не экономить на одной строчке и сделать нормальный for.

Кстати, кто как переводит list comprehension? Для себя решил в устной речи говорить конструктор списков, а в письменной указывать префикс z-, для большей точности :)
а в письменной указывать префикс z-, для большей точности :)
это как?
>>> (1 < 11) > 10
Это вроде очевидно? Булево значение перейдет в int(True), которое будет 1
UFO just landed and posted this here
php -r ""«echo ((int)(1 < 11) > 10)? 'True\n': 'False\n';»""?

Вроде схоже выходит :).
В питоне тоже стоит ручками конвертировать, а то можно наткнуться на непонятности.
Так в Python boolean отсутствует вообще, там все булевые значения сразу храняться в int (0 и 1)
Здраааасьте…
>>> type(True), type(False)
(<type 'bool'>, <type 'bool'>)

Это условные операторы принимают не только bool, но и другие значения.
«subtype» это не одно и тоже:
>>> 1 is 1
True
>>> 1 is True
False
>>> 0 is 0
True
>>> 0 is False
False
Да, не одно и то же, но это означает, что int — это не bool, но bool — это int. Булевы значения не требуют конвертации, они и так хранятся в том же виде, что и int.
А как вы представляете себе хранение bool значения не в виде 0/1?
А как вы представляете себе хранение bool значения не в виде 0/1?
Видели, например, erlang или ocaml.

А вобще, я сказал лишь о том, что какой-то специальной дополнительной конвертации не требуется и непонятностей при этой конвертации быть не может, так как bool — это по сути int.
С таким подходом можно утвержать, что double — это по сути битовый массив.
теоретически, bool в python можно воспринимать как подкласс int. поэтому, тот факт, что bool допускается использовать везде, где можно использовать int, следует из принципа подстановки Лисков. как они хранятся «на самом деле» не имеет ни какого значения.
Знаю, но помню что был PEP где советовали по кодировкам и по конвертации писать явно, т.к. иногда может быть непонятно.
Здорово! Вроде бы обычные вещи и многое знал, но написано от души и подобраны красивые примеры.
Еще один повод сказать коллегам: «Смотрите как это просто сделать на python».
Тотальное выкуривание документации (а желательно на несколько раз) натурально творит чудеса
Ее реально много.
По поводу обмена значений двух переменных без использования третей. В оригинале значения были целыми, а весь смысл был в не использовании дополнительной памяти. А кто знает, что в реальности делает a, b = b, a?
И вообще через третью переменную быстрее: docs.python.org/release/2.3.3/tut/node12.html 10.10
Смотрим байт-код:

>>> def f1():
...     a, b = 0, 1
...     b, a = a, b
...
>>> def f2():
...     a, b = 0, 1
...     c = a
...     a = b
...     b = c
...

>>> dis.dis(f1)
  2           0 LOAD_CONST               3 ((0, 1))
              3 UNPACK_SEQUENCE          2
              6 STORE_FAST               0 (a)
              9 STORE_FAST               1 (b)

  3          12 LOAD_FAST                0 (a)
             15 LOAD_FAST                1 (b)
             18 ROT_TWO
             19 STORE_FAST               1 (b)
             22 STORE_FAST               0 (a)
             25 LOAD_CONST               0 (None)
             28 RETURN_VALUE
>>> dis.dis(f2)
  2           0 LOAD_CONST               3 ((0, 1))
              3 UNPACK_SEQUENCE          2
              6 STORE_FAST               0 (a)
              9 STORE_FAST               1 (b)

  3          12 LOAD_FAST                0 (a)
             15 STORE_FAST               2 ©

  4          18 LOAD_FAST                1 (b)
             21 STORE_FAST               0 (a)

  5          24 LOAD_FAST                2 ©
             27 STORE_FAST               1 (b)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE



Ищем отличия и смотрим, что такое ROT_TWO:

Swaps the two top-most stack items. (дока)

И так, на самом деле вариант с упаковыванием-распаковыванием списков потребляет меньше памяти. Компилятор умный, он оптимизирует.
Инициализация словаря
>>> dict(a=1, b=2, c=3)
{'a': 1, 'c': 3, 'b': 2}

Из питона3 (что-то портировано и на 2.7)
словарь из пар
>>> list(enumerate('abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> dict(list(enumerate('abc')))
{0: 'a', 1: 'b', 2: 'c'}

Метод format у строк
>>> "Вес {weight} кг, цена {price} руб".format(weight=1, price=2)
'Вес 1 кг, цена 2 руб'


Разделение списков в функциональном стиле.
>>> head, *tail = list(range(5))
>>> head
0
>>> tail
[1, 2, 3, 4]
>>> dict(enumerate('abc'))
{0: 'a', 1: 'b', 2: 'c'}

Можно и без промежуточного списка
За что люблю питон, общаясь и читая чужой код, постоянно узнаешь изящные ходы =)
Метод format у строк
>>> "Вес {weight} кг, цена {price} руб".format(weight=1, price=2)
'Вес 1 кг, цена 2 руб'

А мне и так нормально:
'Вес %(weight)d кг, цена %(price)d руб' % {'weight' : 1, 'price' : 2}
:)
В третьем питоне не будет работать :)
Эх, а жаль. А то format'а в 2.5 нет :(
по-моему, «словарь из пар» можно делать уже давно. в python2.5 точно есть.
согласования поправьте, а то голову сломал:
«Но, если передавать два параметра, то первой должен быть callable-объектом, а второй — результатом вызова первого объект, при котором нужно прекратить итерацию»

Спасибо, поправил.
Может и было в комментах, но все-таки мне очень интересно сравнение чисел =)
«Правда и то, что вся магия поломается если добавить скобки:

>>> (1 < 11) > 10
False»

то есть 1<11 дает true, а true — это обычно единица. Так может для достижения TRUE в резулоьтате такого выражения, стоит сравнить так: (1<11)>0? у кого есть питон под рукой, попробуйте плз =)
Да, это будеть True, но не потому что 11 > 0, а потому что True(1) > 0.

> питон под рукой
http://codepad.org
А я оч чем выше говорил? :)
«true — это обычно единица»
извините, отправилось раньше… дополнение:
…, в результате получаем
(1<11)>10
1<11 = true,
true = 1,
1 > 0
Какой пайтон? Вы ебанулись так питон называть?
Python ([ˈpaɪθən]; па́йтон, широко используется также русскоязычное произношение пито́н) [...] Название языка произошло вовсе не от вида пресмыкающихся. Автор назвал язык в честь популярного британского комедийного телешоу 1970-х «Летающий цирк Монти Пайтона». ru.wikipedia.org/wiki/Python
Да, причём написал: (Q&A) нужно ли любить шоу Монти Пайтона, чтобы программировать на этом языке? — не обязательно. Хотя я люблю и то, и другое :)))

А пресмыкающее он обозвал «nasty reptile».
Sign up to leave a comment.

Articles

Change theme settings