[Tutor] Sorting a dictionary in one line?

Magnus Lycka magnus@thinkware.se
Sun Jan 19 17:14:09 2003


At 12:56 2003-01-19 -0800, Terry Carroll wrote:
>This isn't a practical question;

Right. Since the answer is "you can't".

>I just want to get a better handle on why
>something I tried didn't work.

Sure.

>I want to print a dictionary, sorted by key.   This works:

[Conventional method (why do it differently?) snipped.]

>In my first attempt, I tried to combine the sort() and keys() calls, right
>in the for statement, without using a temporary list, and it doesn't work.
>I tried several variations on a theme, but here's a general idea
>illustrating what I was attempting:
>
>for x in dict.keys().sort():
>     print x, dict[x]

>1) Why doesn't this work? If I understand this right, dict.keys() returns
>a list, and lists have a sort() method, which returns a list, which is a
>sequence; so why is this an iteration over a non-sequence?

No. .sort() returns None!

 >>> a = [3,4,2,1]
 >>> print a.sort()
None
 >>> print a
[1, 2, 3, 4]

Lists can obviously be very big. For that reason it's important
that we are able to perform sorts without having to duplicate
the list. Thus .sort() modifies the original list, not a copy of
it. The .sort() method could still have had a "return self" in
the end as a convenience, but it doesn't. The thing is that if
we wrote "sortedList = myList.sort()" it would be very confusing
to discover that "myList" had become sorted in the operation. For
that reason .sort() returns None. You need to do:

sortedList = myList; sortedList.sort()

Now there is no ambiguity.

>2) Not that it's important to do this in one line, but is it possible?

Well, you can write your own function that does this, and call
that in one line... :) That function will be more than one logical
line though.

While I was reading Peter Pan to my son, he added:
>Or, put another way, is it possible to operate on an anonymously sorted
>list (e.g., dict.keys().sort() )?

No. If you do a.b().c().d() etc, the result of this expression
will always be the return value of the last operation. To access
the result of a.b().c() you need to store that, as in

x = a.b().c()
x.d()

This isn't so bad, is it? If we want to work later with a certain
value that pops up in our program, we create a refeence to it,
typically by assigning a variable.

But it might seem a little odd that it's permitted to do such a
meaningless thing as to sort a list that there are no references
to. Maybe a syntax checker or something like that should notice
such things. But it's not so simple. We somehow need to keep track
of functions that neither have varying return values, nor have
any external side effects, and tag warn for performing such methods
on objects that we don't have any references to. Ok, we know that
sort() and reverse() are such methods, but divining whether another
function belongs to this category is non-trivial. And who knows what
the programmer intends. Perhaps he is measuring the time a sort-
operation takes, and doesn't care about the result?


-- 
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