Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 21, 2012 22:40:46

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

Решал задачку 3 отсюда из темы “функции”: http://pyobject.ru/blog/2010/02/04/python-quiz/
Написал:

def gen(a,b):
	lst = []
	for i in xrange(a,b+1):
		lst.append(lambda x: x+i)
	return lst
Вроде, как я полагал, должен возвращаться список функций, суммирующих с аргументом, аргумент должен варьиоваться от a до b, однако возвращается список функций, расположенных, вроде, по разным адресам, но суммирующих только с b. То есть список одинаковых функций. Почему так, подскажите пожалуйста?

Отредактировано vault (Июнь 21, 2012 23:01:59)

Офлайн

#2 Июнь 21, 2012 23:19:43

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

>>> fab_adders = lambda a, b: (lambda x: x + off for off in xrange(a, b + 1))
>>> for adder in fab_adders(0, 5):
...     print adder(10)
...     
... 
10
11
12
13
14
15



Офлайн

#3 Июнь 21, 2012 23:21:33

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

Спасибо. А почему мой код работает неправильно?

Офлайн

#4 Июнь 21, 2012 23:24:18

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

Видимо, lambda-выражение вычисляется после выполнения цикла for, когда значение i равно b.



Офлайн

#5 Июнь 21, 2012 23:28:51

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

Хм.

>>> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
>>> for adder in fab_adders(0, 5):
...     print adder(10)
...     
... 
15
15
15
15
15
15



Отредактировано fata1ex (Июнь 21, 2012 23:32:06)

Офлайн

#6 Июнь 21, 2012 23:30:15

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

fata1ex
Видимо, lambda-выражение вычисляется после выполнения цикла for, когда значение i равно b.


>>> def gen(a,b):
	lst = []
	for i in xrange(a,b+1):
		lst.append(lambda x: x+i)
		print lst[i-a](1)
	return lst
>>> l = gen(0,2)
1
2
3
>>> l
>>> l[0](1)
3

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

Офлайн

#7 Июнь 21, 2012 23:41:23

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

def foo():
    fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
    for adder in fab_adders(0, 1):
        print adder(0)
  
  
foo()

[00:40] home:~/dev pdb lmbd.py
> /home/fata1ex/dev/lmbd.py(3)<module>()
-> def foo():
(Pdb) b foo
Breakpoint 1 at /home/fata1ex/dev/lmbd.py:3
(Pdb) r
> /home/fata1ex/dev/lmbd.py(4)foo()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb) s
> /home/fata1ex/dev/lmbd.py(5)foo()
-> for adder in fab_adders(0, 1):
(Pdb)
--Call--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
--Return--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()->[<functio...b7384ed4>, <functio...b7384e2c>]
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(6)foo()
-> print adder(0)
(Pdb)
--Call--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
--Return--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()->1
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
1
> /home/fata1ex/dev/lmbd.py(5)foo()
-> for adder in fab_adders(0, 1):
(Pdb)
> /home/fata1ex/dev/lmbd.py(6)foo()
-> print adder(0)
(Pdb)
--Call--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
> /home/fata1ex/dev/lmbd.py(4)<lambda>()
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
--Return--
> /home/fata1ex/dev/lmbd.py(4)<lambda>()->1
-> fab_adders = lambda a, b: [lambda x: x + off for off in xrange(a, b + 1)]
(Pdb)
1
> /home/fata1ex/dev/lmbd.py(5)foo()
-> for adder in fab_adders(0, 1):
(Pdb)
--Return--
> /home/fata1ex/dev/lmbd.py(5)foo()->None
-> for adder in fab_adders(0, 1):
(Pdb)
--Return--
> /home/fata1ex/dev/lmbd.py(9)<module>()->None
-> foo()
(Pdb)
--Return--
> <string>(1)<module>()->None

Эээ



Офлайн

#8 Июнь 21, 2012 23:46:18

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

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

Офлайн

#9 Июнь 21, 2012 23:46:24

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/
http://mail.python.org/pipermail/python-bugs-list/2005-March/027801.html
http://bytes.com/topic/python/answers/169732-lambda-functions-within-list-comprehensions

vault, а чего пояснять, я сам в шоке :)

Для print всё ясно - у вас в лямбде и в принте разные i!



Отредактировано fata1ex (Июнь 21, 2012 23:55:09)

Офлайн

#10 Июнь 21, 2012 23:55:49

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Не могу разобраться - почему работает неправильно.

То есть, насколько я понял со своим английским, это тупо баг?
Не понял про разные i - я жеж обращаюсь вроде к одному и тому же элементу массива. В случае принта из функции нулевого элемента получаю 1, а в случае принта вне функции - 3. Массив-то, вроде, один и тот же. Извините, если туплю.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version