Здравствуйте, c-smile, Вы писали:
CS>>>Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать. Кё>>Ты про None? Как быть со списком [None, None, None, 'Value']? CS>Я не знаю что такое None в Python. Это то что возвращает return; (пустой return)?
Да, и результат функции всегда можно класть в список, даже у тебя в TIScript:
function f()
{
}
var a = [f(), f(), f()]; // [nothing,nothing,nothing]
def f():
return
a = [f(), f(), f()]
print a # [None, None, None]
Re[4]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>Отличие в том что я говорил не про генераторы, а про итераторы.
Ну и. Я с помощью генератора создал объект поддерживающий iterator protocol. К слову, нет в python классов итераторов. Есть объекты поддерживающие iterator protocol.
CS>Вот этот пример из статьи CS>во первых некоректен ибо два таких итератора на одной такой коллекции CS>приведут к непредсказуемым результатам — self.current_item будет использоваться CS>во всех for f in bytevalue активных для данного instance.
Не понял. Что конкретно не будет работать? Здесь например всё предсказуемо:
str="hello"
a=ByteValue(str) # current_item для a и b разные
b=ByteValue(str) #
CS>И непонятно как делать rewind такого итератора.
Никак. Для Forward Iterator сделать тоже нельзя, обидно. Но если очень хочется, можешь расширить класс, реализующий iterator protocol
class ByteValue(object):
...
def restart(self):
self.current_item=0
...
iter=ByteValue("hello")
for f in iter:
print f
iter.restart()
for f in iter:
print f
CS>И вообще iterators и generators представляются взаимоисключающими понятиями.
В python почему-то generators это удобный способ создать объект, реализующий iterator протокол.
CS>На самом деле generators достаточно дорогое удовольствие — нужно хранить CS>их call frames в хипе, а не на стеке.
Не нашёл дорогих операций:
CS>У Python не самый быстрый runtime и так. CS>К слову tiscript на типовых тестах быстрее Питона (сравнивал с v. 2.X), но CS>медленне (by design) чем Lua.
Полагаю, что это тема для другого обсуждения.
class Fruits(object):
def __init__(self):
self.__data=["apple","orange","lime","lemon","pear","banan","kiwi","pineapple"]
def forward(self):
idx=0
while idx < len(self.__data):
yield self.__data[idx]
idx=idx+1
def backward(self):
idx=len(self.__data)-1
while idx >= 0:
yield self.__data[idx]
idx=idx-1
fruits=Fruits()
for f in fruits.forward():
print f
for f in fruits.backward():
print f
def range2(start,end):
i=start
while i < end:
yield i
i=i+1
for i in range2(12,24):
print i
Re: [ANN] Введение в итераторы и генераторы в питоне
во первых некоректен ибо два таких итератора на одной такой коллекции
приведут к непредсказуемым результатам — self.current_item будет использоваться
во всех for f in bytevalue активных для данного instance.
И непонятно как делать rewind такого итератора.
И вообще iterators и generators представляются взаимоисключающими понятиями.
На самом деле generators достаточно дорогое удовольствие — нужно хранить
их call frames в хипе, а не на стеке. У Python не самый быстрый runtime и так.
К слову tiscript на типовых тестах быстрее Питона (сравнивал с v. 2.X), но
медленне (by design) чем Lua.
Re[5]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, c-smile, Вы писали:
CS>>Отличие в том что я говорил не про генераторы, а про итераторы. К>Ну и. Я с помощью генератора создал объект поддерживающий iterator protocol. К слову, нет в python классов итераторов. Есть объекты поддерживающие iterator protocol.
А что такое iterator protocol? Это атрибуты __iter__ и next как я понимаю?
А кто их создает для function object?
она генератор? (по смыслу она может и не быть никогда генератором)
Если "да" то на какой фазе у ней создаются эти __iter__ и next?
Далее... обычно параметры передаются в функцию на стеке и там же лежит call frame. За для эффективности.
В случае исполнения первого bc_yield в генераторе параметры и local variables должны быть ммм... unstack call frame — перенесены в
heap. Я чего-то это дело не нашел ...
а нашел... PyFrame_New() ... ну в общем да ...
Мало того что абсолютно все call frames (т.е. вызовы питоновских функций)
оказываются живут в С heap (все те же malloc/free) так еще на каждый вызов питоновской функции это на
самом деле вызов Cшной функции (PyEval_EvalFrameEx?) с 140 байт локальных переменных.
И для чего нужно завершать итератор с помощью exception (StopIteration)?
Кто его кстати бросает в случае генератора?
CS>>Вот этот пример из статьи CS>>во первых некоректен ибо два таких итератора на одной такой коллекции CS>>приведут к непредсказуемым результатам — self.current_item будет использоваться CS>>во всех for f in bytevalue активных для данного instance. К>Не понял. Что конкретно не будет работать? Здесь например всё предсказуемо: К>
К>str="hello"
К>a=ByteValue(str) # current_item для a и b разные
К>b=ByteValue(str) #
К>
Блин, забываю какждый раз что в Питоне нет new. Тогда понятно, спасибо за разъяснение.
CS>>На самом деле generators достаточно дорогое удовольствие — нужно хранить CS>>их call frames в хипе, а не на стеке. К>Не нашёл дорогих операций: К>
Да, уже понял, спасибо. Как оказалось frames в Питоне создаются на каждый вызов в хипе, а не на стеке.
Т.е. yield действительно дешевый в этом случае. Это вызов функций дорогой. И весьма я бы сказал.
Re[6]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>А что такое iterator protocol? Это атрибуты __iter__ и next как я понимаю? CS>А кто их создает для function object? CS>
CS>она генератор? (по смыслу она может и не быть никогда генератором) CS>Если "да" то на какой фазе у ней создаются эти __iter__ и next?
Она генератор всегда, так как внутри тела есть yield. В случае p1==0 генерируется пустая последовательность. В дополнение, генератор не может возвращать значение, то есть return 0 нужно будет заменить на return.
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, c-smile, Вы писали:
CS>>А что такое iterator protocol? Это атрибуты __iter__ и next как я понимаю? CS>>А кто их создает для function object? CS>>
CS>>она генератор? (по смыслу она может и не быть никогда генератором) CS>>Если "да" то на какой фазе у ней создаются эти __iter__ и next?
К>Она генератор всегда, так как внутри тела есть yield. В случае p1==0 генерируется пустая последовательность. В дополнение, генератор не может возвращать значение, то есть return 0 нужно будет заменить на return.
Угу. Так много буковок про в общем-то простую идиому.
CS>>И для чего нужно завершать итератор с помощью exception (StopIteration)? К>Вот что по этому поводу пишет Guido van Rossum
Гвидо не прав.
A special value has the problem that if a sequence ever
contains that special value, a loop over that sequence will
end prematurely without any warning. If the experience with
null-terminated C strings hasn't taught us the problems this
can cause, imagine the trouble a Python introspection tool
would have iterating over a list of all built-in names,
assuming that the special End value was a built-in name!
Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать.
CS>>Кто его кстати бросает в случае генератора? К>Насколько я понимаю, return и конец метода в этом случае преобразуются в raise StopIteration
Блин, как это все мне напоминает "память больше не ресурс" от слонов известного цвета.
Re[8]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>>>И для чего нужно завершать итератор с помощью exception (StopIteration)? К>>Вот что по этому поводу пишет Guido van Rossum
CS>Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать.
Ты про None? Как быть со списком [None, None, None, 'Value']?
Re[9]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, Кодёнок, Вы писали:
CS>>Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать.
Кё>Ты про None? Как быть со списком [None, None, None, 'Value']?
Я не знаю что такое None в Python. Это то что возвращает return; (пустой return)?
Re[10]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>>>Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать. CS>Я не знаю что такое None в Python. Это то что возвращает return; (пустой return)?
Это он и есть, вполне себе полноценный объект:
def f(): return
print type(f())
печатает
<type 'NoneType'>
Re[11]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, c-smile, Вы писали:
CS>>>>Есть такое value называется void или nothing. Технически оно наличествует всегда. Надо было его использовать. Кё>>>Ты про None? Как быть со списком [None, None, None, 'Value']? CS>>Я не знаю что такое None в Python. Это то что возвращает return; (пустой return)?
Кё>Да, и результат функции всегда можно класть в список, даже у тебя в TIScript:
Кё>
Кё> function f()
Кё> {
Кё> }
Кё> var a = [f(), f(), f()]; // [nothing,nothing,nothing]
Кё>
Да действительно это сейчас можно сделать, но ... !
Есть четыре байткода (у меня) которые записывают значения для хранения:
BC_ESET (offset,value) - сохранение в локальную переменную/параметр функции.
BC_VSET (index,value) - сохранение в элемент массива.
BC_PSET (key,value) - сохранение в property объекта.
BC_GSET (key,value) - сохранение в global/namespace объекте.
достаточно изменить эти методы на предмет проверки на VM::nothingValue и этот
самый nothing никогда не появится в коллекциях и значениях переменных, т.е. в enumerable things.
Вот простая функция которая это делает у меня:
inline value value_to_set(value t) { return t == VM::nothingValue? VM::undefinedValue : t; }
Т.е. все 'nothing' становится non-storable value, при сохранении заменяется на 'undefined'
Короче не rocket science.
Re[12]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>Т.е. все 'nothing' становится non-storable value, при сохранении заменяется на 'undefined' CS>Короче не rocket science.
Хз Как быть с:
a[0] = f()
assert(a[0] == f()) // should fail?
Re[13]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, c-smile, Вы писали:
CS>>Т.е. все 'nothing' становится non-storable value, при сохранении заменяется на 'undefined' CS>>Короче не rocket science.
Кё>Хз Как быть с:
Кё>
Кё>a[0] = f()
Кё>assert(a[0] == f()) // should fail?
Кё>
А вот это вопрос философический.
1) Во первых никто не обещает что a[0] = anything; a[0] == anything -> true
Set an element of a collection by index/key это вычисляемая операция.
Т.е. value может в принципе замещено каким-то другим в коде.
Т.е. on "should fail?" answer is "it may fail".
2) В принципе можно рассмотреть логическую систему в которой
undefined == <nothing>, но вместе с тем undefined === <nothing> -> false
3a) Вариант А: в случае присвоения something = <nothing> можно бросать исключение.
3b) Вариант B: Сравнение something == <nothing> приводит к исключению. Ибо nothing это неопределенность.
Что лучше?
Я лично склоняюсь к #2
Re: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, c-smile, Вы писали:
CS>А вот это вопрос философический. CS>1) Во первых никто не обещает что a[0] = anything; a[0] == anything -> true
Вполне естественно ожидать, что после a = b будет истинно a == b. Если кто-то допустим сделает из “a” property, самопроизвольно меняющей значение на рандом, то это просто нехорошо.
CS>2) В принципе можно рассмотреть логическую систему в которой CS>3a) Вариант А: в случае присвоения something = <nothing> можно бросать исключение. CS>3b) Вариант B: Сравнение something == <nothing> приводит к исключению. Ибо nothing это неопределенность. CS>Что лучше?
Я не понимаю, зачем в языке три значения «нет информации» — null, undefined, nothing (в Javascript вроде два? nothing нет; по мне, тоже не очень). В питоне как-то логичнее — если чего-то нет, то его нет, к нему нельзя получить доступ (a[b] → исключение, если ключа b нет в словаре), если отсутствие надо обозначить (null), используется None (a[b] = None, если надо специально что-то сохранить), других вариантов нет.
Re[2]: [ANN] Введение в итераторы и генераторы в питоне
Здравствуйте, kronos_vano, Вы писали:
_>На питоне можно как-нить аналогично: _>[1,2,3].each do |x| _> puts x _>end _>power = lambda {|x| puts x*x } _>mul_2 = lambda {|x| puts x+x } _>[1,2,3].each(&power) _>[1,2,3].each(&mul_2)
Это вопрос или утверждение?
for x in [1,2,3]:
print(x)
power = lambda x: print(x*x)
mul_2 = lambda x: print(x+x)
list(map(power, [1,2,3])) # если нужно значение
all(map(power, [1,2,3])) # просто вычислить все
for x in map(mul_2, [1,2,3]): pass # более читабельно