Hey folks, I'm sitting over here in the AppleScript talk and Jacob is explaining a module called 'appscript' that interfaces to the Apple Events system. What caught my eye was this example: from appscript import * ab = app('Address Book') people = ab.people.filter(its.emails != []) That last line asks the Address Book to select only entries with e-mail addresses. The weird 'its' object comes from the appscript module -- asking for its properties and using operators causes it to set up thunks for you. It dawned on me that you could use this idea to make the whole filter/lambda experience vastly more pleasant. I whipped up a quick implementation: >>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>> Look ma, no lambdas! I bet someone has already done this before, right? -- ?!ng
For filter and map, list comprehensions and generator expressions are the answer.
numbers = [5, 9, 56, 34, 1, 24, 37, 89] [x for x in numbers if x < 30] [5, 9, 1, 24] (x for x in numbers if x < 30) <generator object at 0x00B1FCD8> list(_) [5, 9, 1, 24]
Jeremy On Wed, 23 Mar 2005 10:33:53 -0600 (CST), Ka-Ping Yee <python-dev@zesty.ca> wrote:
Hey folks,
I'm sitting over here in the AppleScript talk and Jacob is explaining a module called 'appscript' that interfaces to the Apple Events system.
What caught my eye was this example:
from appscript import * ab = app('Address Book') people = ab.people.filter(its.emails != [])
That last line asks the Address Book to select only entries with e-mail addresses. The weird 'its' object comes from the appscript module -- asking for its properties and using operators causes it to set up thunks for you.
It dawned on me that you could use this idea to make the whole filter/lambda experience vastly more pleasant. I whipped up a quick implementation:
>>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>>
Look ma, no lambdas!
I bet someone has already done this before, right?
-- ?!ng _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/jeremy%40alum.mit.edu
On Wed, 23 Mar 2005 10:33:53 -0600 (CST), Ka-Ping Yee <python-dev@zesty.ca> wrote:
It dawned on me that you could use this idea to make the whole filter/lambda experience vastly more pleasant. I whipped up a quick implementation:
>>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>>
Look ma, no lambdas!
I bet someone has already done this before, right?
I thought about it, but couldn't convince myself that it would work properly in all cases. I was thinking in terms of operator overloading of everything possible - how did you do it? Paul.
Paul Moore <p.f.moore@gmail.com> wrote:
On Wed, 23 Mar 2005 10:33:53 -0600 (CST), Ka-Ping Yee <python-dev@zesty.ca> wrote:
It dawned on me that you could use this idea to make the whole filter/lambda experience vastly more pleasant. I whipped up a quick implementation:
>>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>>
Look ma, no lambdas!
I bet someone has already done this before, right?
I thought about it, but couldn't convince myself that it would work properly in all cases. I was thinking in terms of operator overloading of everything possible - how did you do it?
PyTables allows something very similar for "in-kernel" searches of data, but only on a single constraint. I would imagine that Ka-Ping did it by only allowing a single operation per item. - Josiah
On Wed, 23 Mar 2005, Josiah Carlson wrote:
Paul Moore <p.f.moore@gmail.com> wrote:
I thought about it, but couldn't convince myself that it would work properly in all cases. I was thinking in terms of operator overloading of everything possible - how did you do it?
PyTables allows something very similar for "in-kernel" searches of data, but only on a single constraint. I would imagine that Ka-Ping did it by only allowing a single operation per item.
You can do more than one operation, but the usage is still quite limited. The item placeholder must be the first operand for it to work. >>> numbers = [3, 8, 4, 1, 2] >>> filter(_ < 5, numbers) [3, 4, 1, 2] >>> map(_ * 5 + 7, numbers) [10, 15, 11, 8, 9] I tried implementing __len__, but that doesn't work because Python enforces a type restriction. >>> words = 'lovely spam and eggs'.split() >>> filter(len(_) == 4, words) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: __len__() should return an int __getitem__ and __getattr__ mostly work. However, in order to call a method on the placeholder you have to add an underscore to distinguish it from retrieving an attribute. >>> filter(_.endswith_('s'), words) ['eggs'] You can check out http://zesty.ca/python for the gory details. As Jeremy wrote, the proper way to do map and filter is to use a list comprehension, so these are bad examples. The original motivation was to provide a way to write lambda expressions for cases where you aren't doing map or filter. For that, it works, but only in limited cases. I realize this isn't that practical. It's mainly for your amusement -- yet another in a long tradition of hacks that use operator overloading to hijack the Python parser. (Also a long tradition of me doing silly things in public.) -- ?!ng
Ka-Ping Yee <python-dev@zesty.ca> wrote:
On Wed, 23 Mar 2005, Josiah Carlson wrote:
Paul Moore <p.f.moore@gmail.com> wrote:
I thought about it, but couldn't convince myself that it would work properly in all cases. I was thinking in terms of operator overloading of everything possible - how did you do it?
PyTables allows something very similar for "in-kernel" searches of data, but only on a single constraint. I would imagine that Ka-Ping did it by only allowing a single operation per item.
You can do more than one operation, but the usage is still quite limited. The item placeholder must be the first operand for it to work.
>>> numbers = [3, 8, 4, 1, 2] >>> filter(_ < 5, numbers) [3, 4, 1, 2] >>> map(_ * 5 + 7, numbers) [10, 15, 11, 8, 9]
Your implementation "works" by not crashing, but that last map should certainly return [22, 47, 27, 12, 17] rather than what it does. It may be extensible to actually work the way I expect such operations to work. - Josiah
Ka-Ping Yee wrote:
It dawned on me that you could use this idea to make the whole filter/lambda experience vastly more pleasant. I whipped up a quick implementation:
>>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>>
Look ma, no lambdas!
What does you implementation do for this:
somevar = False filter(_ and False, numbers)
Reinhold
On Wed, 23 Mar 2005, Reinhold Birkenfeld wrote:
What does you implementation do for this:
somevar = False filter(_ and False, numbers)
It fails. (For the same reason that __len__ doesn't work -- Python insists that __nonzero__ must return an int.) Though i must say i have no idea what you are trying to do here. If you filter on False, you'll always get an empty list. -- ?!ng
On Mar 23, 2005, at 1:16 PM, Ka-Ping Yee wrote:
On Wed, 23 Mar 2005, Reinhold Birkenfeld wrote:
What does you implementation do for this:
somevar = False filter(_ and False, numbers)
It fails. (For the same reason that __len__ doesn't work -- Python insists that __nonzero__ must return an int.) Though i must say i have no idea what you are trying to do here. If you filter on False, you'll always get an empty list.
Similarly, appscript provides function versions of operators named such as AND and OR. I suppose there could be a length one as well (in AppleScript terminology, it would be called count), or you could technically denote it as __len__(), but that's quite ugly. I had implemented something quite similar to this a long time ago, but considered it "evil" and never used it for anything: http://tinyurl.com/6ft4h -bob
Ka-Ping Yee wrote:
On Wed, 23 Mar 2005, Reinhold Birkenfeld wrote:
What does you implementation do for this:
somevar = False filter(_ and False, numbers)
It fails. (For the same reason that __len__ doesn't work -- Python insists that __nonzero__ must return an int.) Though i must say i have no idea what you are trying to do here. If you filter on False, you'll always get an empty list.
I know; I just wanted to show that this approach can be very misleading as and/or can't be overloaded. Reinhold -- Mail address is perfectly valid!
On Wed, 23 Mar 2005 10:33:53 -0600 (CST), Ka-Ping Yee <python-dev@zesty.ca> wrote:
Hey folks,
>>> from placeholder import _ >>> numbers = [5, 9, 56, 34, 1, 24, 37, 89] >>> filter(_ < 30, numbers) [5, 9, 1, 24] >>> map(_ + 10, numbers) [15, 19, 66, 44, 11, 34, 47, 99] >>>
Look ma, no lambdas!
I bet someone has already done this before, right?
I tried it once before: ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/local-distfiles/perky/anonfunc-1.0.tar.gz
from anonfunc import * f = (arg0 * arg1 + 3 * arg2) ** 2 f(5, 6, 7) 2601
f = kw1 and kw2 f(kw1=False, kw2=True) True f(kw2=False, kw1=True) False
But there were some serious drawbacks to use it instead of lambda. * (a,b,c) is impossible * unable to use it with list comprehensions and generator expressions * can't call functions and use its return value * and many builtin functions as you described (such as len(), sorted()) Hye-Shik
participants (7)
-
Bob Ippolito
-
Hye-Shik Chang
-
Jeremy Hylton
-
Josiah Carlson
-
Ka-Ping Yee
-
Paul Moore
-
Reinhold Birkenfeld