472,798 Members | 1,213 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,798 software developers and data experts.

proposals for having more fun with map

hi all,

i've got a few proposals to do, in one way or another, with the map
builtin. i'd like to hear what people think.

firstly, collections, and things that look like collections, should
support the call operator; the implementation should look like:

def __call__(self, arg):
return self[arg]

then, you could use collections as functions. after all, collections and
functions are just two different ways of representing mappings (dicts are
general mappings, and lists are mappings of the natural numbers which have
a contiguous domain), so it makes sense for them to be somewhat
interchangeable. specifically, this would make it possible to use dicts
and lists as first arguments to map, eg:

details = {
"surnname": "Cleese",
"firstname": "John",
"dob": 19391027,
"birthplace": "Weston-super-Mare",
"height: 1.95,
"favourite work": "the documentary about lemurs"
}
template = ("firstname", "surname", "height")
info = map(details, template)

okay, so maybe you're not convinced, but this is something i find myself
wanting to do all the time, so i either end up throwing lambdas all over
the place to glue the dicts into map, or writing a little helper function
like so:

def functor(dict):
return lambda arg: dict[arg]

this isn't hard, of course, but it's the sort of thing that ought to be
done once and only once.

there's a case to be made that function objects should also have
__getitem__, so they look like mappings, but that's harder, since they
can't really supply a keys method, so they can't be full mappings.
however, i do wonder if sequences could have a keys method, which would
look like:

def keys(self):
return range(len(self))

so they look like mappings of a range of the natural numbers. the problem
with that is that the sequence and mapping versions of __iter__ are
incompatible. oh well.

secondly, map should work on dicts as well as sequences. map has semantics
that look like this:

map(fn, x)[i] = fn(x[i])

at the moment, x has to be a sequence; i'd like to allow x to be a
mapping. the implementation is a doddle:

def mapdict(fn, dict):
mdict = []
for key in dict:
mdict[key] = fn(dict[key])
return mdict

again, trivial, but if i'm writing this out in almost every program i
write, other people must be too, so it's worth putting in the core.

now, that function is a version of map for dicts; i'd like to see one
function which supports sequences and mappings. i'm not entirely sure how
you'd decide whether an input was a sequence or a mapping, though; the
best i've come up with is using hasattr(x, "keys") to see if it looks like
a mapping (which falls down if we give sequences a keys method!).

thirdly, i'd like map to try to preserve the type of the sequence; if you
feed it a tuple, you get a tuple back, and if you feed it a string, you
get a string back. this isn't hard to do, but is hard to do well. the
simple way forward is to pull out the type of the parameter and try to use
it to construct a return value from a list:

def preservingmap(fn, seq):
mseq = map(fn, seq)
try:
mseq = type(seq)(mseq)
except TypeError:
pass
return mseq

however, this requires the constructor of sequence-like types to
essentially be a copy constructor; this may be too great a restriction on
programmers.

also, we'd need to redefine the implementation of __str__ for sequences;
at present, it's the same as __repr__, but that doesn't work in the above
scheme, since it's far from being a copy constructor. in particular, we
want it to be such that, for a string s, str(list(s)) == s. i think it has
to look like:

def __str__(self):
return reduce(lambda a, b: a + b, map(str, self))

so that it just returns the concatenation of the stringification of its
elements. this isn't much use for the general task of displaying lists to
humans, but that's what repr is for. str is about converting an object to
a string, and this is surely the most natural way for sequences.

anyway, that's it. am i bonkers, or does any of that sound like a good
idea?

tom

--
Punk's not sexual, it's just aggression.

Jul 18 '05 #1
6 1248
>>>>> "Tom" == Tom Anderson <tw**@urchin.earth.li> writes:

Tom> wanting to do all the time, so i either end up throwing lambdas all over
Tom> the place to glue the dicts into map, or writing a little helper function
Tom> like so:

Tom> def functor(dict):
Tom> return lambda arg: dict[arg]

See http://aspn.activestate.com/ASPN/Coo.../Recipe/305318

#itemgetter: also of course works with dictionaries
data= ( {'name':'fred','score':50},{'name':'betty','score' :75})
print map(operator.itemgetter('name'),data)
['fred', 'betty']


Tom> this isn't hard, of course, but it's the sort of thing that
Tom> ought to be done once and only once.

Indeed ;-).

Tom> again, trivial, but if i'm writing this out in almost every
Tom> program i write, other people must be too, so it's worth
Tom> putting in the core.

Actually, the more likely future of map is moving *out* of the core,
to a "functional" module of some sort. List comprehensions (and soon
genexps) are the recommended approach.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #2
On Sat, 09 Oct 2004 13:10:51 +0100, Tom Anderson wrote:
hi all,

i've got a few proposals to do, in one way or another, with the map
builtin. i'd like to hear what people think.


Most of your proposals are implementable today with a pure Python module,
albeit with some subclasses of built-ins.

If you're serious about this, I'd suggest bundling all your suggestions
into a module and pointing people at them to try them out, including
several examples of the advantages you want to point out.

The best argument for proposals is to try it and find it useful, and since
yours are easy to implement, I'd suggest taking advantage of that.

Jul 18 '05 #3
On Sat, 9 Oct 2004, Jeremy Bowers wrote:
On Sat, 09 Oct 2004 13:10:51 +0100, Tom Anderson wrote:
i've got a few proposals to do, in one way or another, with the map
builtin. i'd like to hear what people think.
Most of your proposals are implementable today with a pure Python module,
albeit with some subclasses of built-ins.


true - in fact, i wrote such a module to make sure that this was true!

the problem is the 'albeit'; for it all to work properly, it needs some
cooperation from core types, without users going round wrapping things all
the time. still, you can probably get at least 80% of it without doing
anything exciting.
If you're serious about this, I'd suggest bundling all your suggestions
into a module and pointing people at them to try them out, including
several examples of the advantages you want to point out.

The best argument for proposals is to try it and find it useful, and
since yours are easy to implement, I'd suggest taking advantage of that.


well said. i'll bundle them up and stick them somewhere; it'll have to
wait for my broadband to come through, though ...

tom

--
I came here to chew gum and kick ass

Jul 18 '05 #4
On 9 Oct 2004, Ville Vainio wrote:
>> "Tom" == Tom Anderson <tw**@urchin.earth.li> writes:

Tom> wanting to do all the time, so i either end up throwing lambdas all over
Tom> the place to glue the dicts into map, or writing a little helper function
Tom> like so:

Tom> def functor(dict):
Tom> return lambda arg: dict[arg]

See http://aspn.activestate.com/ASPN/Coo.../Recipe/305318


of course! i really should use the operator package more; it just feels
kind of clunky to me.
Tom> again, trivial, but if i'm writing this out in almost every
Tom> program i write, other people must be too, so it's worth
Tom> putting in the core.

Actually, the more likely future of map is moving *out* of the core, to
a "functional" module of some sort. List comprehensions (and soon
genexps) are the recommended approach.


NOOOOOOO!!!!!!!!!!!!!!!!!! one by one, my favourite languages are being
mutilated beyond recognition ... </overreaction>

tom

--
I came here to chew gum and kick ass

Jul 18 '05 #5
Tom Anderson <tw**@urchin.earth.li> wrote:
Actually, the more likely future of map is moving *out* of the core, to
a "functional" module of some sort. List comprehensions (and soon
genexps) are the recommended approach.


NOOOOOOO!!!!!!!!!!!!!!!!!! one by one, my favourite languages are being
mutilated beyond recognition ... </overreaction>


Yep, an overreaction. Moving a function among different modules of the
standard library (e.g., from builtins to a new module 'functional') is
very different from changing the language.
Alex
Jul 18 '05 #6
Tom Anderson <tw**@urchin.earth.li> wrote:
...
details = {
"surnname": "Cleese",
"firstname": "John",
"dob": 19391027,
"birthplace": "Weston-super-Mare",
"height: 1.95,
"favourite work": "the documentary about lemurs"
}
template = ("firstname", "surname", "height")
info = map(details, template)
Use map(details.get, template) and you can get this today. No reason to
change dicts for this purpose.
okay, so maybe you're not convinced, but this is something i find myself
wanting to do all the time, so i either end up throwing lambdas all over
the place to glue the dicts into map, or writing a little helper function
like so:

def functor(dict):
return lambda arg: dict[arg]

this isn't hard, of course, but it's the sort of thing that ought to be
done once and only once.
It is -- you simply need the bound method somedict.get (in 2.4 it might
be slightly faster to call somedict.__getitem__, I think in 2.3
somedict.get is faster and in any case it _is_ nicer to type!-).

however, i do wonder if sequences could have a keys method, which would
look like:

def keys(self):
return range(len(self))

so they look like mappings of a range of the natural numbers. the problem
with that is that the sequence and mapping versions of __iter__ are
incompatible. oh well.
Yep, not worth doing.

secondly, map should work on dicts as well as sequences. map has semantics
that look like this:

map(fn, x)[i] = fn(x[i])

at the moment, x has to be a sequence; i'd like to allow x to be a
mapping. the implementation is a doddle:
Nope, a dict is accepted as x today:
d=dict(a=23,b=42,c=69)
map(lambda x:x, d) ['a', 'c', 'b']


This cannot be changed w/o backwards incompatibilities (so, propose it
for Python 3000 -- won't get in before then, as it would break some
current, perfectly correct programs).

anyway, that's it. am i bonkers, or does any of that sound like a good
idea?


Why should the two be mutually incompatible?-)

Seriously: some of your ideas may have merit but you should realize no
changes that break currently working programs are gonna get in until 3.0
at the earliest, and even in 3.0 the focus will be on simplification.
If you're keep on your backwards-incompatible proposals you might be
luckier with some of the various python-like languages which are
springing up _without_ the backwards compatibility requirements of
Python, such as bobo or Prothon. For Python itself, you must deal with
the additional burden of backwards compatibility on top of everything...
Alex
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

36
by: Antoon Pardon | last post by:
I'm rather new at this, so I don't know how I should introduce this, nor whether these ideas are worth much but here goes. What I would like to change is access to variables on an intermediate...
14
by: Martin v. Lwis | last post by:
The Python Software Foundation is seeking grant proposals for projects related to the further development of Python, Python-related technology, and educational resources. The PSF plans to issue...
0
by: Kevin Altis | last post by:
Please submit your tutorial and session proposals for the Python track by February 13th. The information and relevant URLs are below. ka --- The Call for Proposals has just opened for the...
0
by: Kevin Altis | last post by:
OSCON 2006: Opening Innovation http://conferences.oreillynet.com/os2006/ Save the date for the 8th annual O'Reilly Open Source Convention, happening July 24-28, 2006 at the Oregon Convention...
0
by: Kevin Altis | last post by:
OSCON 2006: Opening Innovation http://conferences.oreillynet.com/os2006/ Save the date for the 8th annual O'Reilly Open Source Convention, happening July 24-28, 2006 at the Oregon Convention...
0
by: Kevin Altis | last post by:
Save the date for the 8th annual O'Reilly Open Source Convention, happening July 24-28, 2006 at the Oregon Convention Center in beautiful Portland, Oregon. Call For Participation...
0
by: Kevin Altis | last post by:
OSCON 2007 http://conferences.oreillynet.com/os2007/ Save the date for the 9th annual O'Reilly Open Source Convention, happening July 23-27, 2007 at the Oregon Convention Center in beautiful...
0
by: David Goodger | last post by:
Thanks to all the proposal authors so far, we have received lots of proposals for PyCon talks & tutorials. But we'd like to have even more. Alas, the proposal submission deadline should have been...
0
by: Aahz | last post by:
Call for proposals -- PyCon 2009 -- <http://us.pycon.org/2009/> =============================================================== Want to share your experience and expertise? PyCon 2009 is looking...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.