重新审视匿名函数:元组操作 [英] Anonymus functions revisited : tuple actions

查看:64
本文介绍了重新审视匿名函数:元组操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


感谢您的关注!


我认为我的建议更多是考虑到Rons修改了exec而不是

Pythons lambda。


当乔治提出他的拆包行为时,列表补偿作为一包

suggar:


1. [x,y,for(x,y,z = 0)in(1,2,3),(4,5),(6,7,8)]


我在随后的lambda风格中解释它:


2. [(lambda x,y,z = 0:x * yz)(* v)对于v in(1,2,3),(4,5),(6,7,8)]


这是等价的,如果Georges语法成为标准Python 。


这可以激发对元组的全新观点,因为在其他元组上打开包装

可以推广到非常相似的匿名函数

到Pythons lambda,但不是Python lambda,因为不同的

范围规则

最近由Rons和Georges在这个帖子中发帖说明。


记住已经很好了可发布的表达式:

Hi all,

thanks for Your attention !

I think my proposal was more in mind of Rons modified exec than
Pythons lambda.

When George proposed his unpacking behavoir for list-comps as a pack of
suggar:

1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]

I interpreted it in a subsequent posting in lambda fashion:

2. [(lambda x,y,z=0:x*y-z)(*v) for v in (1,2,3), (4,5), (6,7,8)]

which would be equivalent, if Georges syntax became standard Python.

This motivates a fresh view on tuples as unpacking actions on other tuples
which could be generalized to anonymus functions which are quite similar
to Pythons lambda but are NOT the Python lambda because of different
scoping rules
which was addressed lately by Rons and Georges postings in this thread.

Remember the already admissable expression:

[x * yz for(x,y,z)in(1,2,3) ),(4,5,6)]
[-1,14] x,y
[x*y-z for (x,y,z) in (1,2,3),(4,5,6)] [-1,14] x,y



(4,5)


x和y是在list-comp之外可见的绑定变量!


因此它将与(x,y,z) - > ; (x,y,z)当它被应用于任何元组

(a,b,c)时有3个元素。它不会返回(a,b,c)但是(x,y,z)与

x = a,y = b,z = c。这就是为什么链接

元组动作很简单的原因。

在1.我们实际上有两个不同的元组动作:


f =(x,y,z = 0) - > (x,y,z)

g =(x,y,z) - > x * yz


可以通过go f链接。


如果我们在list-comp 1中扩展了tuple-action的概念。我们得到


[(x,y,z) - > x * yz代表(x,y,z = 0) - >(x,y,z)in( 1,2,3),(4,5),(6,7,8)]


这仍然是明确的简短形式


[((x,y,z) - > x * yz)(x,y,z)(x,y,z = 0) - >(x,y,z)in(1 ,2,3),(4,5),(6,7,8)]。


仍然没有像真实的那样的免费/未绑定变量/>
lambda calculus

可以被另一个lambda绑定。元组操作显然会扫除

被误导的关联 - 对于Pythonistas来说确实不是这样;)


也许Guidos厌恶FP有点误导,因为它实际上是

语言,但隐藏为特殊规则。


问候凯


(4,5)

x and y are bound variables that are visible outside the list-comp !

So it would be with (x,y,z) -> (x,y,z) when it is applied to any tuple
(a,b,c) with 3 elements. It does not return (a,b,c) but (x,y,z) with
x = a, y = b, z = c. This is the reason why it is simple to chain
tuple-actions.

In 1. we have actually two different tuple actions:

f = (x,y,z=0) -> (x,y,z)
g = (x,y,z) -> x*y-z

which is chainable by g o f.

If we expand the notion of tuple-action in the list-comp 1. we get

[(x,y,z)->x*y-z for (x,y,z=0)->(x,y,z) in (1,2,3), (4,5), (6,7,8)]

which is still a short form of the explicit

[((x,y,z)->x*y-z)(x,y,z) for (x,y,z=0)->(x,y,z) in (1,2,3), (4,5), (6,7,8)].

There is still no such thing as a free/unbound variable as in real
lambda calculus
that can be bound by another lambda. Tuple actions would obviously sweep
off this
misguided association - o.k not so for Pythonistas ;)

Maybe Guidos aversion against FP is bit misguided too because it is
actually in
the language but hidden as special rules.

Regards Kay


推荐答案

Kay Schluehr写道:
Kay Schluehr wrote:
大家好,

谢谢为了你的注意!

我认为我的建议更多是考虑到Rons修改了exec而不是Pythons lambda。

当George提出他的拆包行为列表comps作为一包的含糖:

1. [x * yz for(x,y,z = 0)in(1,2,3),(4,5),( 6,7,8)]

我在随后的lambda方式中解释它:

2. [(lambda x,y,z = 0:x * yz )(* v)for v in(1,2,3),(4,5),(6,7,8)]
Hi all,

thanks for Your attention !

I think my proposal was more in mind of Rons modified exec than
Pythons lambda.

When George proposed his unpacking behavoir for list-comps as a pack of
suggar:

1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]

I interpreted it in a subsequent posting in lambda fashion:

2. [(lambda x,y,z=0:x*y-z)(*v) for v in (1,2,3), (4,5), (6,7,8)]




Argh!愚蠢的我 !我从没想过要使用明星运营商:(

谢谢凯。


(剪辑)


-

bruno desthuilliers

python -c" print''@''。join([''。''。join([w [:: - 1] ]对于p.split(''。'')]中的w for

p in''o **** @ xiludom.gro''。split(''''')]) "



Argh! Stupid me ! I never thought of using the star operator for this :(
Thanks Kay.

(snip)

--
bruno desthuilliers
python -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) for
p in ''o****@xiludom.gro''.split(''@'')])"


2005年3月23日星期三06:21:30 +0100,Kay Schluehr< ka ********* @ gmx.de>

写道:
On Wed, 23 Mar 2005 06:21:30 +0100, Kay Schluehr <ka*********@gmx.de>
wrote:
我认为我的提议更多是关于Rons修改的exec而不是
Pythons lambda。

当乔治提出他的拆包行为为list-comps作为一包的含糖:

1. [x * yz for(x,y,z = 0)in(1,2, 3),(4,5),(6,7,8)]

我在随后的lambda风格中解释它:

2. [(lambda x ,y,z = 0:x * yz)(* v)对于v in(1,2,3),(4,5),(6,7,8)]
I think my proposal was more in mind of Rons modified exec than
Pythons lambda.

When George proposed his unpacking behavoir for list-comps as a pack of
suggar:

1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]

I interpreted it in a subsequent posting in lambda fashion:

2. [(lambda x,y,z=0:x*y-z)(*v) for v in (1,2,3), (4,5), (6,7,8)]




谢谢凯,这一切真的很有趣,我是通过这些讨论学习了很多关于语言的知识。

以下是我今天早上做的一个实验。 :-)


我很惊讶它工作得很好,虽然我不认为

应该用在任何真正的生产代码中。不是它的现在形式

无论如何。


想法是有一个像程序代码元组的容器类

可以移动并在需要时使用。非常灵活,也许

如果没有字符串和exec / eval()函数可以完成

吗?


Ron_Adam

#credito.py

导入类型


类代码(元组):

"""

内联代码存储类


name = code((''expression'',''expression'',... ))

varables = name.do([locals()],[''invars''],''outvars'')


这是实验。


警告:这是实验性的!这门课没有经过测试。它还使用了exec和eval(),这可能是一个安全风险。

""

def do( self,* args):

如果type(args [0])== type({}):

parentnames = args [0]

else:

parentnames = globals()

if len(args)> 1:

argslist = args [1] .split ('','')

else:

argslist = args

for a argslist:

if parentnames.has_key(a):

exec a +''= parentnames [a]''

for c in self:

exec(c )

返回eval(args [-1])#最后一个参数是返回

varable(s)。

if __name__ == ''__main__'':

"""

测试一下。这只是有效的,而不是什么。

"""


#从左到右的订单。

y = 3

打印代码((''y = y * 2'',''x = y ** 2''))。do(''x'')


#***稍后定义并使用! ***

mybutton_action = code((''z = y * 2'',''x = z ** 2'',''result = x + 2'')) />
y = 1

打印mybutton_action.do('''',''结果'')

y = 10

打印mybutton_action.do(''y'',''结果'')

y = 100

print mybutton_action.do(''y'',''结果'')


#返回多个值。

toxyz = code(('''x * = 2'',''y * = 2''' ,''尝试:z\\\
except:z = 0'',''z * = 2''))

x = 2

y = 3

#z = 4

a,b,c = toxyz.do(''x,y,z'')

打印a,b,c


#1。[x * yz表示(1,2,3),(4,5),(6,7,8)中的(x,y,z = 0) ]

打印代码((''r = []'',''代表x,y,z

[(1,2,3),(4 ,5,0),(7,8,9)]:r.append(x * yz)''))。do(''r'')


#或...这里需要使用尾随逗号来制作单元组。

打印代码((''r = list([x * yz代表x,y,z]

(1,2,3),(4,5,0),(7,8,9)])'',))。做(''r'')


#返回前的过程列表。

打印代码((''r = [x代表范围内的x(1,11)]'',''r = r * 2'')) .do(''r'')


#来自函数内:

#我们需要传递locals()以便它可以找到变量。

def fn1():

x = 5

y = 10

lfunction = code((''z = x * 2 + y'',))。do(locals(),''x,y'',''z'')

print lfunction

fn1()



Thank you Kay, All of this is really intersting and I''m learning a
lot about the language through these discussions.
The following is an experiment I did this morning. :-)

I was surprised it worked as well as it did, although I don''t think it
should be used in any real production code. Not in it''s present form
anyway.

The idea is to have a container class like a tuple for program code
that can be moved around and used when needed. Very flexable, maybe
if it could be done without the strings and the exec/eval() functions
in it?

Ron_Adam
# codedo.py
import types

class code(tuple):
"""
Inline Code Storage Class

name = code((''expression'',''expression'',...))
varables = name.do([locals()],[''invars''],''outvars'')

This is experimental.

Warning: This is experimental! This class has not
been tested. It also uses exec, and eval(), which
can be a security risk.
"""
def do(self, *args ):
if type(args[0]) == type({}):
parentnames = args[0]
else:
parentnames = globals()
if len(args)>1:
argslist = args[1].split('','')
else:
argslist = args
for a in argslist:
if parentnames.has_key(a):
exec a+''=parentnames[a]''
for c in self:
exec(c)
return eval(args[-1]) # The last argument are the return
varable(s).
if __name__ == ''__main__'':
"""
Test it. This is only what works, not what doesn''t.
"""

# Left to Right order.
y=3
print code((''y=y*2'',''x=y**2'')).do(''x'')

# *** Define and use later! ***
mybutton_action = code((''z=y*2'',''x=z**2'',''result=x+2''))
y = 1
print mybutton_action.do(''y'',''result'')
y = 10
print mybutton_action.do(''y'',''result'')
y = 100
print mybutton_action.do(''y'',''result'')

# Return multiple values.
toxyz = code((''x*=2'',''y*=2'',''try:z\nexcept:z=0'',''z*=2''))
x = 2
y = 3
#z = 4
a, b, c = toxyz.do(''x,y,z'')
print a, b, c

# 1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]
print code((''r=[]'',''for x,y,z in
[(1,2,3),(4,5,0),(7,8,9)]:r.append(x*y-z)'')).do(''r'')

# or... trailing comma needed here to make a uni-tuple.
print code((''r=list([x*y-z for x,y,z in
(1,2,3),(4,5,0),(7,8,9)])'',)).do(''r'')

# post process list before returning.
print code((''r = [ x for x in range(1,11) ]'',''r=r*2'')).do(''r'')

# From within a function:
# We need to pass locals() to so it can find the variables.
def fn1():
x = 5
y = 10
lfunction = code((''z = x*2+y'',)).do(locals(),''x,y'',''z'')
print lfunction
fn1()


Ron写道:
2005年3月23日星期三06:21:30 +0100,Kay Schluehr< ka ** *******@gmx.de>
写道:
On Wed, 23 Mar 2005 06:21:30 +0100, Kay Schluehr <ka*********@gmx.de>
wrote:
我认为我的建议更多是考虑到Rons修改的exec比
Pythons lambda。

当乔治提出他的拆包行为为list-comps作为一个包
ofsuggar:

1。 [x,yz for(x,y,z = 0)in(1,2,3),(4,5),(6,7,8)]

我在一个解释它随后以lambda方式发布:

2。 [(lambda x,y,z = 0:x * yz)(* v)v in(1,2,3),(4,5),(6,7,8)]
谢谢Kay,所有这些都很有趣,我正在通过这些讨论学习很多语言。
I think my proposal was more in mind of Rons modified exec than
Pythons lambda.

When George proposed his unpacking behavoir for list-comps as a pack ofsuggar:

1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]

I interpreted it in a subsequent posting in lambda fashion:

2. [(lambda x,y,z=0:x*y-z)(*v) for v in (1,2,3), (4,5), (6,7,8)]
Thank you Kay, All of this is really intersting and I''m learning a
lot about the language through these discussions.




谢谢,Ron!

以下是我今天早上做的一个实验。 :-)

我很惊讶它工作得很好,虽然我不认为
它应该用在任何真正的生产代码中。不管它现在是什么形式


想法是有一个像程序代码元组的容器类,可以移动并在需要时使用。非常灵活,也许
如果可以在没有字符串和exec / eval()函数的情况下完成它吗?



Thanks, Ron !
The following is an experiment I did this morning. :-)

I was surprised it worked as well as it did, although I don''t think it should be used in any real production code. Not in it''s present form
anyway.

The idea is to have a container class like a tuple for program code
that can be moved around and used when needed. Very flexable, maybe
if it could be done without the strings and the exec/eval() functions
in it?




我个人不喜欢不喜欢使用exec和eval来评估用户输入不同的东西。


你很依赖在线评估声明通过适应传统的Python语法来支持
。我认为可以进一步打破

语法偏见并应用元组动作:)


玩元组动作有点表明这个概念非常强大,可以用来创建简单的语句。


首先必须修补语义:


我们有


(x,y,z = 0) - > (x,y,z)


作为元组赋值


((x,y,z = 0) - >(x ,y,z))(a,b,c)=(x = a,y = b,z = c)


但目前尚不清楚


(x,y,z = 0) - > x * y-z


实际上是指?

建议:


(x,y = 0) - > x * y => ((x,y = 0) - > x * y)(a,b) - > (x = a,y = b),a * b

(x,y = 0) - > (x * y)=> ((x,y = 0) - >(x * y))(a,b) - > (x = a * b,y = b)


所以(x,y = 0) - > x * y将结果附加到参数元组。


备注:这是同构形式


(x,y = 0,res =无) - > ((x,y),x * y)


但现在变得更难识别


(x,y,res =无) - > ((x,y),x * y)

with

x * y


提供编译器提示:


(x,y,()) - > x * y


现在我们准备好几个例子:

默认值:

(i) - > (0)#i = 0

就地增量:

(i) - > i + 1#i = i + 1


条件表达式:

(i) - > i< 3#i,res = i,i< 3


简单转换:

(res) - > (res + i ** 2)#res = res + i ** 2

将While循环定义为函数:


def While(par, cond,change,action):

par(无)#create default

res = 0

而cond(par)[1]:

行动(res)

更改(标准杆)

返回res


让's'将它应用于一些元组动作:


而((i) - >(0),(i) - > i< 3,(i) - >(i + 1),(res) - >(res + i ** 2))


并逐步评估:


1. par (无)< => (i) - >(0)(无)#(i)=(0)

2. cond(par)[1]< => (i) - > i< 3(0)#(i,c)=(0,True)

3. action(res)< => (res) - > (res + i ** 2)(0)#(res)=(0)

4.更改(par)< => (i) - >(i + 1)(0)#(i)=(1)

5. cond(par)[1]< => (i) - > i< 3< 3(1)#(1,c)=(0,True)

6. action(res)< => (res) - > (res + i ** 2)(0)#(res)=(1)

7.更改(par)< => (i) - >(i + 1)(1)#(i)=(2)

5. cond(par)[1]< => (i) - > i< 3< 3(2)#(2,c)=(0,True)

6. action(res)< => (res) - > (res + i ** 2)(1)#(res)=(5)

7.更改(par)< => (i) - >(i + 1)(2)#(i)=(3)

5. cond(par)[1]< => (i) - > i< 3(2)#(2,c)=(0,假)

休息


=> res = 5

如果我们自定义其他控制流原语For和If它应该

只能通过使用这个原语来创建一个小语言。


根据我们的定义很明显我们可以在飞行中替换参数




conds = [(i) - > i< 3,(i) - > i + 2< 7,(i) - > i> = 0]


[while((i) - > ;(0),cond,(i) - >(i + 1),(res) - >(res + i ** 2))for cond in

conds]


=> [5,29,0]

在Python中使用会不会很有趣?


唯一的缺点:看起来不像可执行的伪代码再说:(

问候凯



I personally don''t like using exec and eval for stuff different from
evaluating user input.

You rely much on "evaluate statement on the line" by adapting
conventional Python syntax. I think one can go a bit further breaking
the syntactical prejudices and apply tuple-actions :)

Playing a bit with tuple-actions shows that the concept is quite
powerfull and can be used to create simple statements.

First of all the semantics has to be patched:

We have

(x,y,z=0) -> (x,y,z)

as a tuple assignment

((x,y,z=0)->(x,y,z))(a,b,c) = (x=a,y=b,z=c)

But it is not clear what

(x,y,z=0) -> x*y-z

actually means?
Proposal:

(x,y=0) -> x*y => ((x,y=0)->x*y) (a,b) -> (x=a,y=b),a*b
(x,y=0) -> (x*y) => ((x,y=0)->(x*y))(a,b) -> (x=a*b,y=b)

So (x,y=0) -> x*y is appending the result to the argument tuple.

Remark: this is isomorph to

(x,y=0,res=None) -> ((x,y),x*y)

but it becomes harder now to identify

(x,y,res=None) -> ((x,y),x*y)
with
x*y

Provide a compiler-hint:

(x,y,()) -> x*y

Now we are ready for a few examples:
default value:
(i) -> (0) # i = 0

inplace increment:
(i) -> i+1 # i = i+1

conditional expression:
(i) -> i<3 # i,res = i,i<3

simple transformation:
(res) -> (res+i**2) # res = res+i**2
Define a While loop as a function:

def While( par, cond, change, action):
par(None) # create default
res = 0
while cond(par)[1]:
action(res)
change(par)
return res

Let''s apply it to some tuple actions:

While((i)->(0), (i)->i<3, (i)->(i+1), (res)->(res+i**2))

and evaluate While stepwise:

1. par(None) <=> (i)->(0)(None) # (i) = (0)
2. cond(par)[1] <=> (i)->i<3(0) # (i,c) = (0,True)
3. action(res) <=> (res) -> (res+i**2)(0) # (res) = (0)
4. change(par) <=> (i)->(i+1)(0) # (i) = (1)
5. cond(par)[1] <=> (i)->i<3(1) # (1,c) = (0,True)
6. action(res) <=> (res) -> (res+i**2)(0) # (res) = (1)
7. change(par) <=> (i)->(i+1)(1) # (i) = (2)
5. cond(par)[1] <=> (i)->i<3(2) # (2,c) = (0,True)
6. action(res) <=> (res) -> (res+i**2)(1) # (res) = (5)
7. change(par) <=> (i)->(i+1)(2) # (i) = (3)
5. cond(par)[1] <=> (i)->i<3(2) # (2,c) = (0,False)
break

=> res = 5
If we customize the other control flow primitives For and If it should
be possible to create a little language only by using this primitives.

It is obvious by definition of our While that we can replace arguments
on the fly:

conds = [(i)->i<3, (i)->i+2<7, (i)->i>=0]

[ While((i)->(0), cond, (i)->(i+1), (res)->(res+i**2)) for cond in
conds]

=> [5,29,0]
Wouldn''t it be fun to use in Python?

Only drawback: does not look like executable pseudo-code anymore :(
Regards Kay


这篇关于重新审视匿名函数:元组操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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