curly-brace-aphobic?

Quinn Dunkan quinn at bolivar.ugcs.caltech.edu
Mon Jan 29 14:50:41 EST 2001


On Mon, 29 Jan 2001 08:01:55 GMT, C.Laurence Gonsalves
<clgonsal at keeshah.penguinpowered.com> wrote:
>On Sun, 28 Jan 2001 22:04:38 -0600, Grant Griffin
><not.this at seebelow.org> wrote:
>>Hi Gang,
>>
>>I'm sure this has been asked a thousand times, but I haven't seen it
>>asked lately (or ever <wink>).
>>
>>Why does Python use square braces ([]) instead of curly braces ({})
>>when accessing dictionaries?

While sequences and mappings are different, access is the same.  Think of it
this way:

import operator
a = [0, 1, 2]
d = {1: 'a', 2: 'b'}
t = (9, 8, 7)
for obj in a, d, t:
    print operator.__getitem__(obj, 1)

>Actually, the thing that's always bugged me is that Python makes a
>distinction between subscripting (__getattr__) and function calls
>(__call__). Mathematically speaking, a dictionary is really just a
>function that maps from 'keys' to 'values'.

Even haskellers usually don't implement finite maps and arrays as functions
(though they usually acknowledge that would be the elegant solution).

So even in a language where functions are the major important element,
efficiency dictates a data-oriented view.  And python is pretty data-oriented
anyway, so a functional representation would be out of character.  And
mutation is important in python, while a functional representation gives no
opportunity for that.

>It always seems silly to me that given:
>
>    m = {'one': 1, 'two':2}
>    l = ['two', 'one']
>
>one can't write:
>
>    map(m, l)

What if 'm' implemented both __call__ and __getitem__?  If you really like the
functional thing:

import UserDict
class FDict(UserDict.UserDict):
    def __call__(self, key):
        return self[key]
    def __add__(self, other): # we could define just a method, but functions
                              # don't have methods but '+' is a method too :)
        # incidentally, I think this indicates a bug in UserDict, which should
        # use isinstance to avoid breaking when inherited
        d = self.data.copy()
        d.update(other.copy())
        return d

Of course, to be consistent here, the only way to change an FDict is to write:

d = old_dict + {'new': 'changes'}

... which forces one to introduce the bizarre concept of adding a function to
a literal, and is also not the most efficient thing in the world, considering
that the usual use of python dicts is incremental mutation, and python
naturally has no optimizations to detect when a value is unused afterwards and
switch to mutation in that case.

>I'm not sure why you need to be reminded whether something is a sequence
>or a dictionary.

Another way to think of it is that 'sequence' is an iteration pattern.
'dictionary' is a data structure.  For example, eiffel has seperate iterator
classes that capture common iteration patterns, which can be applied by any
class that implements their routines (or 'effects' their 'deferreds', if you
like).



More information about the Python-list mailing list