[Tutor] Sorting a dictionary in one line?

Magnus Lycka magnus@thinkware.se
Mon Jan 20 12:31:22 2003


At 17:13 2003-01-20 +0100, Charlie Clark wrote:
>It's a funny name and I've still got to get used to it. But the Python
>Cookbook has some good illustrations of its use and it makes more sense to
>me than map, lambda and reduce. I'd throw in zip as another thing likely to
>cause confusion.

Well, the name might suggest that it has something to do
with compression I guess... I think the name zip fits much
better here than in compression programs. They should really
be called squeeze or pack or something like that. But prior
art matters. But I think syntax is more important than function
names...

>This is exactly the kind of confusion I get into. I had tested stuff in the
>shell before writing it in the mail.

Not the next line. ;)

> > >d = {'b':2, 'c':3, '2'}
> >
> > What did you try to do here? A listionary? ;)
>hehe
>hands up who else frequently types the wrong symbols for the data structure!
>This isn't helped by the fact that {[]} all require the modifier key on a
>German keyboard :-(

And Swedish etc.

> >From the Terminal:

Good! :)

># is keys() a method or an attribute?

All methods are attributes. This particular attribute is a
method. Typically, only methods handle the () after the
attribute name. (There are some non-method attributes that
can be invoked like methods though. But never mind that now.)

 >>> print d.keys
<built-in method keys of dict object at 0x017615F8>

Here we come back to another Python principle:
"Explicit is better than implicit."

In many programming languages, the parenthesis can be skipped
when you call a function without parameters. In some languages,
you can even skip the parenthesis when you have parameters. The
explicit distinction between a function object and the invocation
of a function object makes it simple to pass objects around etc.

sin = math.sin

is certainly not the same as

sin = math.sin()

> >>> a = d.keys()

The d.keys() method call returns a list. I.e. a new object is
created here, and you make if accessible through the variable 'a'.

There is no list of keys as a built-in component of a dict. Dicts
aren't built like that. If they were, I guess we would have used
d.keys instead of d.keys(). As we said. Explicit is better than
implicit.

> >>> d['GvR'] = 'BDFL'
> >>> a
>['Magnus', 'Charlie']
> >>> d.keys()
>['Magnus', 'Charlie', 'GvR']
> >>> a == d.keys() # shows why '=' != '==' in Python!
>0

Right. As you see 'a' points to a 'normal' list. typing
"print type(a)" will print <type 'list'>, not <type 'some
magical thingie that changes in sync with a dict'>

>mm, 'a' is assigned to a list created when the method d.keys() is called?

Yes.

>ie. d.keys() isn't an attribute of the dictionary although my brain tells
>it's kind of obvious that a dictionary has an index...

No, it hasn't. Not like that. It's a hash table. I.e. you perform a
mathematical operation on the key value to find a slot in a list, and
then you only have to look through a few items (often just one) to find
your value. This makes it possible to find a value almost as quickly in
a dict with 100 000 items as in one with 10 items.

>so when I change the dictionary 'a' isn't affected because it is referring
>to an object which itself is not actually referencing the dictionary. Is
>this correct?

Yes. .keys() retrieves all the keys in the dict, creates a list on the
heap, just as any list you create in you code, and put the key values in
that list. It's completely decoupled from the dictionary after that. It's
just a plain list. You might remove all the keys from that list and store
statistics from your poker games there instead.

>It would seem to be me to be okay for 'a' to be referencing a
>dictionary attribute called keys and for this be continually updated but
>this isn't the case and this is for a reason. I'm just not very sure of the
>reason...

Well, I can name a few...

* As I said, dicts don't really have index lists like you think. Have
   a look in dictobject.c in the Python source package, or read Vol 3
   of Don Knuth's "The Art of Computer Programming", page 528- (Algorithm D.)
* It would have been invoked as d.keys, not d.keys()
* keys = d.keys; keys.append(5) would add a new key without
   a value to the list? Or should it be a read-only attribute? In that
   case you can't sort it, so what would the point be then?


-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus@thinkware.se