奇怪的lambda重新绑定/重新分配没有我这样做 [英] Weird lambda rebinding/reassignment without me doing it

查看:56
本文介绍了奇怪的lambda重新绑定/重新分配没有我这样做的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用验证

时从不重新定义或重新分配列表,但因为它将修改后的列表吐出来,以某种方式意味着

修改后的列表是其中的一部分环境而不是旧环境。

i认为函数内部发生的事情仍然存在于函数内部

意味着什么出来是独立于进来的。

如果我想将我发送的列表作为参数发送给函数我需要做x = func(x)而不仅仅是func(x)而x是神奇的是什么

来自func()。

没有Python关闭或者这不是什么意思?

def验证(已放置):

student = round(random.random()* 401)

如果学生被安置:

返回验证(已放置)

否则:

placement.append(学生)

返回学生,放置


def val(已放置):

student = round(random.random()* 401)

如果学生被安置:

返回n验证(已放置)

其他:

placement.append(学生)

返回学生


>> g = lambda x:validate(x)
l = []
for x in range (1,10):



g(l)

(141.0,[141.0])

(19.0,[141.0,19.0])

(86.0,[141.0,19.0,86.0])

(120.0,[141.0,19.0, 86.0,120.0])

(76.0,[141.0,19.0,86.0,120.0,76.0])

(262.0,[141.0,19.0,86.0,120.0,76.0, 262.0])

(234.0,[141.0,19.0,86.0,120.0,76.0,262.0,234.0])

(74.0,[141.0,19.0,86.0,120.0, 76.0,262.0,234.0,74.0])

(325.0,[141.0,19.0,86.0,120.0,76.0,262.0,234.0,74.0,325.0])


>> g = lambda x:val(x)
l = []
for x in范围(1,10) :



g(l)

183.0

33.0

315.0

244.0

308.0

168.0

146.0

378.0

297.0


>>>

解决方案

Python并没有对变量使用值语义,而是使用引用语义:


a = [1]

b = a


在许多语言中,你现在有2个列表。在Python中你仍然有一个列表,

,a和b都引用它。


现在如果修改数据(列表),两个变量将改变


a.append(2)#就地修改列表

打印b#将打印[1,2]

如果你不想要这个,你应该在某处复制


a = a + [2]





b = a [:]

需要一点时间习惯,但在实践中它非常方便。

阅读关于''immutable''和''mutable''类型的文档。

(我希望这是一个常见问题解答,但我不能很快找到匹配的条目)

Albert


文章

< 02 ***************** ***************** @ z72g2000hsb。 googlegroups.com>,

ssecorp< ci ********** @ gmail.comwrote:


我是从来没有重新定义或重新分配列表时使用验证

,但因为它将修改后的列表吐出来,以某种方式意味着

修改后的列表是环境的一部分,而不是旧的。

i认为函数内部发生的事情会停留在函数内部

意味着什么出来是独立于什么。

含义如果我希望我发送的列表作为参数发送给函数我必须做x = func(x)而不仅仅是func(x)而x是神奇的是什么

来自func()。



函数不能修改全局变量的值

(除非它指定global)。它没有重新分配任何东西。

但是在下面的函数中你没有重新分配变量,

你是_modifiying_一个对象。函数_can_修改你传递给它的

对象:


>> def DoesntReassign(x):



.... x = 0

....


>> def修改(x):



.... x.append(0)

....


>> x = 42
DoesntReassign(x)
x



42


>> x = []
修改(x)
x



[0]


嗯,看看这个:


>> x = []
id(x)



404296


>>修改(x)
x



[0]


>> id(x)



404296

''x''指的是对

调用Modifies之前和之后的完全相同的对象。该函数有_modified_

对象,但它没有重新定义或重新分配任何东西。


没有Python有关闭或者不是什么这是关于?


def验证(已放置):

student = round(random.random()* 401)

如果学生被安置:

返回验证(已放置)

其他:

placement.append(学生)

返回学生,放置


def val(已放置):

student = round(random.random()* 401)

如果学生被安置:

返回验证(已放置)

其他:

placement.append(学生)

返回学生


> g = lambda x:validate(x)
l = []
for x在范围内(1,10):



g(l)


(141.0,[141.0] )

(19。 0,[141.0,19.0])

(86.0,[141.0,19.0,86.0])

(120.0,[141.0,19.0,86.0,120.0])

(76.0,[141.0,19.0,86.0,120.0,76.0])

(262.0,[141.0,19.0,86.0,120.0,76.0,262.0])

(234.0,[141.0,19.0,86.0,120.0,76.0,262.0,234.0])

(74.0,[141.0,19.0,86.0,120.0,76.0,262.0,234.0,74.0} ])

(325.0,[141.0,19.0,86.0,120.0,76.0,262.0,234.0,74.0,325.0])


> g = lambda x:val(x)
l = []
对于范围内的x(1,10):



g(升)


183.0

33.0

315.0

244.0

308.0

168.0

146.0

378.0

297.0


>>



-

David C. Ullrich





David C. Ullrich写道:


文章

< 02 ************** @ z72g2000hsb。 googlegroups.com>,

ssecorp< ci ********** @ gmail.comwrote:


>我在使用验证时从不重新定义或重新分配列表
但是因为它将修改后的列表吐出来,以某种方式表示修改后的列表是环境的一部分而不是旧的列表。
我认为函数内部发生的事情会停留在函数内部
意味着出现的内容与进入函数无关。
如果我想将列表作为参数发送给函数我是什么意思
必须做x = func(x)而不只是func(x)和x神奇地是什么来自func()。



函数无法修改全局变量的值



是的它可以。


>> a = []
def f():



a.append(''yes can can'')


>> f()
a



[''是的我可以'']


(除非它指定全局)。它没有重新分配任何东西。



语句''global a''允许f * *重新绑定*全局*名称*

''a''。 变量这个词几乎不应该用于讨论Python

,因为它通常不清楚它是指一个名称(或集合

slot)还是一个对象绑定到它。


但是在下面的函数中你没有重新分配变量,

你是_modifiying_一个对象。函数_can_修改你传递给它的
对象:



它可以修改它可以访问的任何可变对象。
< blockquote class =post_quotes>


> Python没有封闭或者这不是什么意思?



Python确实有闭包。这不是那个。


> def validate(已放置):
student = round(random.random( )* 401)
如果学生被安置:
返回验证(放置)
否则:
placement.append(学生)
返回学生,放置



删除它。下面是多余的。


> def val(已放置):
student = round(random.random ()* 401)
如果学生被安置:
返回验证(已放置)
否则:
placement.append(学生)
返回学生



我相信这相当于


def addval(已放置):

而True:

student = round(random.random()* 401)

如果学生没有被安置:

break

puts.append(学生)

返回学生


虽然这可以避免无限期的递归深度问题,但它并没有避免
避免无限期的问题。使用random.shuffle,或编写你的

自己的版本,如果这样做练习。除非您实际直接使用添加的值,否则请考虑删除

return语句。它更容易记住,addval在没有返回的情况下变异''置'。


>>>> g = lambda x:validate(x)



这是双重患病。


首先,永远不要写一个''name = lambda ...''语句,因为它等同于一个def语句的
,除了结果函数对象缺少一个

正确的.funcname属性。以上只是简单的缩写

def g(x):返回validate(x)

3个字符。另一个原因是lambda形式更多

经常让人们陷入下一个错误。


其次,永远不要写一个函数(使用def或lambda)只需

就会返回参数的函数。包装什么也没做!这个

浪费了你和翻译的时间和空间。上面的

在功能上相当于

g =验证

如果你想要,你可以命名函数''g''当你定义它。


>>>> l = []



在某些字体中,''l''和''''几乎相同;请使用

else的公共代码,通过发布它来做到这一点;-)


>>>> for x in range(1,10):


g(l)



如上所述,g包装器没用。

addval(l)


希望这会有所帮助。


Terry Jan Reedy


I am never redefining the or reassigning the list when using validate
but since it spits the modified list back out that somehow means that
the modified list is part of the environment and not the old one.
i thought what happend inside a function stays inside a function
meaning what comes out is independent of what comes in.
Meaning if I want the list I send as a parameter to the function I
have to do x = func(x) and not just func(x) and x is magically what
comes out of func().
Doesnt Python have closure or that isnt what this is about?
def validate(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student, placed

def val(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student

>>g = lambda x:validate(x)
l=[]
for x in range(1,10):

g(l)
(141.0, [141.0])
(19.0, [141.0, 19.0])
(86.0, [141.0, 19.0, 86.0])
(120.0, [141.0, 19.0, 86.0, 120.0])
(76.0, [141.0, 19.0, 86.0, 120.0, 76.0])
(262.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0])
(234.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0])
(74.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0])
(325.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0, 325.0])

>>g = lambda x:val(x)
l=[]
for x in range(1,10):

g(l)
183.0
33.0
315.0
244.0
308.0
168.0
146.0
378.0
297.0

>>>

解决方案

Python doesn''t use value semantics for variables but reference semantics:

a = [1]
b = a

In many languages, you''d now have 2 lists. In Python you still have one list,
and both a and b refer to it.

Now if you modify the data (the list), both variables will change

a.append(2) # in-place modification of the list
print b # will print [1,2]
If you don''t want this, you should make a copy somewhere

a = a + [2]

or

b = a[:]
It takes a bit of getting used to, but it is very handy in practice.
Read the docs about ''immutable'' and ''mutable'' types.
(I expected this to be a FAQ, but I couldn''t quickly find a matching entry)
Albert


In article
<02**********************************@z72g2000hsb. googlegroups.com>,
ssecorp <ci**********@gmail.comwrote:

I am never redefining the or reassigning the list when using validate
but since it spits the modified list back out that somehow means that
the modified list is part of the environment and not the old one.
i thought what happend inside a function stays inside a function
meaning what comes out is independent of what comes in.
Meaning if I want the list I send as a parameter to the function I
have to do x = func(x) and not just func(x) and x is magically what
comes out of func().

A function cannot modify the value of a global variable
(unless it specifies "global"). It doesn''t reassign anything.
But in the functions below you''re not reassigning a variable,
you''re _modifiying_ an object. A function _can_ modify an
object you pass to it:

>>def DoesntReassign(x):

.... x = 0
....

>>def Modifies(x):

.... x.append(0)
....

>>x=42
DoesntReassign(x)
x

42

>>x=[]
Modifies(x)
x

[0]

Hmm, look at this:

>>x=[]
id(x)

404296

>>Modifies(x)
x

[0]

>>id(x)

404296

''x'' refers to exactly the same object before and after
the call to Modifies. The function has _modified_ that
object, but it hasn''t redefined or reassigned anything.

Doesnt Python have closure or that isnt what this is about?
def validate(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student, placed

def val(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student

>g = lambda x:validate(x)
l=[]
for x in range(1,10):

g(l)
(141.0, [141.0])
(19.0, [141.0, 19.0])
(86.0, [141.0, 19.0, 86.0])
(120.0, [141.0, 19.0, 86.0, 120.0])
(76.0, [141.0, 19.0, 86.0, 120.0, 76.0])
(262.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0])
(234.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0])
(74.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0])
(325.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0, 325.0])

>g = lambda x:val(x)
l=[]
for x in range(1,10):

g(l)
183.0
33.0
315.0
244.0
308.0
168.0
146.0
378.0
297.0

>>

--
David C. Ullrich




David C. Ullrich wrote:

In article
<02**********************************@z72g2000hsb. googlegroups.com>,
ssecorp <ci**********@gmail.comwrote:

>I am never redefining the or reassigning the list when using validate
but since it spits the modified list back out that somehow means that
the modified list is part of the environment and not the old one.
i thought what happend inside a function stays inside a function
meaning what comes out is independent of what comes in.
Meaning if I want the list I send as a parameter to the function I
have to do x = func(x) and not just func(x) and x is magically what
comes out of func().


A function cannot modify the value of a global variable

Yes it can.

>>a=[]
def f():

a.append(''yes I can'')

>>f()
a

[''yes I can'']

(unless it specifies "global"). It doesn''t reassign anything.

The statement ''global a'' would allow f to *rebind* the global *name*
''a''. The word ''variable'' should almost not be used in discussing Python
since it is often unclear whether it refers to a name (or collection
slot) or an object bound thereto.

But in the functions below you''re not reassigning a variable,
you''re _modifiying_ an object. A function _can_ modify an
object you pass to it:

It can modify any mutable object it can access.

>Doesnt Python have closure or that isnt what this is about?

Python does have closures. This is not about that.

>def validate(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student, placed

Delete this. It is redundant with the below.

>def val(placed):
student = round(random.random()*401)
if student in placed:
return validate(placed)
else:
placed.append(student)
return student

I believe this is equivalent to

def addval(placed):
while True:
student = round(random.random()*401)
if student not in placed:
break
placed.append(student)
return student

While this avoids the indefinite recursion depth problem, it does not
avoid the indefinite time problem. Use random.shuffle, or write your
own version if doing this for practice. Also consider removing the
return statement unless you actually directly use the added value. It
is easier to remember that addval mutates ''placed'' without the return.

>>>>g = lambda x:validate(x)

This is doubly diseased.

First, never write a ''name = lambda...'' statement since it is equivalent
to a def statement except that the resulting function object lacks a
proper .funcname attribute. The above only trivially abbreviates
def g(x): return validate(x)
by 3 characters. Another reason is that the lambda form somehow more
often tricks people into the next mistake .

Second, never write a function (with either def or lambda) that simply
returns a function of the argument(s). The wrapping does nothing! This
is a waste of time and space for both you and the interpreter. The
above is functionally equivalent to
g = validate
and if you want that, you could name the function ''g'' when you define it.

>>>>l=[]

In some fonts, ''l'' and ''1'' are nearly identical; please use something
else for public code, which you made this to be by posting it;-)

>>>>for x in range(1,10):

g(l)

As said, the ''g'' wrapper is useless.
addval(l)

Hope this helps.

Terry Jan Reedy


这篇关于奇怪的lambda重新绑定/重新分配没有我这样做的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆