473,796 Members | 2,501 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why are there no ordered dictionaries?

This is probably a FAQ, but I dare to ask it nevertheless since I
haven't found a satisfying answer yet: Why isn't there an "ordered
dictionary" class at least in the standard list? Time and again I am
missing that feature. Maybe there is something wrong with my programming
style, but I rather think it is generally useful.

I fully agree with the following posting where somebody complains why so
very basic and useful things are not part of the standard library:
http://groups.google.com/group/comp....52d2f771a49857

Are there plans to get it into the standard lib sometime?

-- Christoph
Nov 22 '05
210 10560
On Sun, 20 Nov 2005 22:03:34 +0100, Christoph Zwerschke <ci**@online.de > wrote:
Ordering the keys isn't the normal case, and can be done easily when
needed.


That depends. Maybe I do not want the keys to be sorted alphabetically,
but according to some criteria which cannot be derived from the keys
themselves.

You mean involving also the values? What's wrong with
sorted(plaindic t.items(), key=your_orderi ng_function) ?
def show(*a): print a ... sorted(dict((c, ord(c)) for c in 'abcd').items() , key=show) (('a', 97),)
(('c', 99),)
(('b', 98),)
(('d', 100),)
[('a', 97), ('c', 99), ('b', 98), ('d', 100)]

What key function would you like, to generate the value that is actually used
to define the ordering?
sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[0]) [('a', 97), ('b', 98), ('c', 99), ('d', 100)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[1]) [('a', 97), ('b', 98), ('c', 99), ('d', 100)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:-t[1]) [('d', 100), ('c', 99), ('b', 98), ('a', 97)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[1]&1) [('b', 98), ('d', 100), ('a', 97), ('c', 99)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,t[1])) [('b', 98), ('d', 100), ('a', 97), ('c', 99)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,-t[1])) [('d', 100), ('b', 98), ('c', 99), ('a', 97)]
And being able to reverse the end result is handy sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,-t[1]), reverse=True)

[('a', 97), ('c', 99), ('b', 98), ('d', 100)]

You may need to upgrade your Python though ;-)

Regards,
Bengt Richter
Nov 22 '05 #51
On Sun, 20 Nov 2005 22:03:34 +0100, Christoph Zwerschke <ci**@online.de > wrote:
Ordering the keys isn't the normal case, and can be done easily when
needed.


That depends. Maybe I do not want the keys to be sorted alphabetically,
but according to some criteria which cannot be derived from the keys
themselves.

You mean involving also the values? What's wrong with
sorted(plaindic t.items(), key=your_orderi ng_function) ?
def show(*a): print a ... sorted(dict((c, ord(c)) for c in 'abcd').items() , key=show) (('a', 97),)
(('c', 99),)
(('b', 98),)
(('d', 100),)
[('a', 97), ('c', 99), ('b', 98), ('d', 100)]

What key function would you like, to generate the value that is actually used
to define the ordering?
sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[0]) [('a', 97), ('b', 98), ('c', 99), ('d', 100)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[1]) [('a', 97), ('b', 98), ('c', 99), ('d', 100)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:-t[1]) [('d', 100), ('c', 99), ('b', 98), ('a', 97)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:t[1]&1) [('b', 98), ('d', 100), ('a', 97), ('c', 99)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,t[1])) [('b', 98), ('d', 100), ('a', 97), ('c', 99)] sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,-t[1])) [('d', 100), ('b', 98), ('c', 99), ('a', 97)]
And being able to reverse the end result is handy sorted(dict((c, ord(c)) for c in 'abcd').items() , key=lambda t:(t[1]&1,-t[1]), reverse=True)

[('a', 97), ('c', 99), ('b', 98), ('d', 100)]

You may need to upgrade your Python though ;-)

Regards,
Bengt Richter
Nov 22 '05 #52

Bengt Richter wrote:
On Sun, 20 Nov 2005 22:03:34 +0100, Christoph Zwerschke <ci**@online.de > wrote:
Ordering the keys isn't the normal case, and can be done easily when
needed.


That depends. Maybe I do not want the keys to be sorted alphabetically,
but according to some criteria which cannot be derived from the keys
themselves.

You mean involving also the values? What's wrong with
sorted(plaindic t.items(), key=your_orderi ng_function) ?

Not according to the content of the data, not just the "key". Or in
other words, some other metadata that is not present in the data. A
typical thing, like order of creation. Or some arbitary order. For
example :

I present a data grid/table in a HTML form and the user just drag and
drop and rearrange the columns order.

Of course, you may say, just put another column that represent
this(some reporting programs I have seen do it this way) and that is an
option but not the only option.

Nov 22 '05 #53

Ben Finney wrote:
bo****@gmail.co m <bo****@gmail.c om> wrote:
[sort by] some other metadata that is not present in the data.
[...]
Of course, you may say, just put another column that represent
this(some reporting programs I have seen do it this way) and that is
an option but not the only option.


It's a pretty good option, and very commonly used. It's known as the
"Schwartzia n transform", or more descriptively, the "Decorate, Sort,
Undecorate" pattern.

Whether it is a good option is judged by the person implement it as he
is the one seeing the whole thing, and not some snippet(or concept) on
the usenet.

Nov 22 '05 #54

Ben Finney wrote:
bo****@gmail.co m <bo****@gmail.c om> wrote:
[sort by] some other metadata that is not present in the data.
[...]
Of course, you may say, just put another column that represent
this(some reporting programs I have seen do it this way) and that is
an option but not the only option.


It's a pretty good option, and very commonly used. It's known as the
"Schwartzia n transform", or more descriptively, the "Decorate, Sort,
Undecorate" pattern.

Whether it is a good option is judged by the person implement it as he
is the one seeing the whole thing, and not some snippet(or concept) on
the usenet.

Nov 22 '05 #55
bo****@gmail.co m wrote:
Fredrik Lundh wrote:
but you can easily generate an index when you need it:

index = dict(d)

name, type = index["pid"]
print name

the index should take less than a microsecond to create, and since it
points to the members of the original dict, it doesn't use much memory
either...

Using the same logic, we don't need types other than string in a DBMS
as we can always convert a string field into some other types when it
is needed.


No, that's not the same logic. The dict() in my example doesn't convert be-
tween data types; it provides a new way to view an existing data structure.
There's no parsing involved, nor any type guessing. And given the use case,
it's more than fast enough, and doesn't copy any data.

If you think that's the same thing as parsing strings, you've completely missed
the point.

</F>

Nov 22 '05 #56
bo****@gmail.co m wrote:
Fredrik Lundh wrote:
but you can easily generate an index when you need it:

index = dict(d)

name, type = index["pid"]
print name

the index should take less than a microsecond to create, and since it
points to the members of the original dict, it doesn't use much memory
either...

Using the same logic, we don't need types other than string in a DBMS
as we can always convert a string field into some other types when it
is needed.


No, that's not the same logic. The dict() in my example doesn't convert be-
tween data types; it provides a new way to view an existing data structure.
There's no parsing involved, nor any type guessing. And given the use case,
it's more than fast enough, and doesn't copy any data.

If you think that's the same thing as parsing strings, you've completely missed
the point.

</F>

Nov 22 '05 #57

Fredrik Lundh wrote:
bo****@gmail.co m wrote:
Fredrik Lundh wrote:
but you can easily generate an index when you need it:

index = dict(d)

name, type = index["pid"]
print name

the index should take less than a microsecond to create, and since it
points to the members of the original dict, it doesn't use much memory
either...

Using the same logic, we don't need types other than string in a DBMS
as we can always convert a string field into some other types when it
is needed.


No, that's not the same logic. The dict() in my example doesn't convert be-
tween data types; it provides a new way to view an existing data structure.
There's no parsing involved, nor any type guessing. And given the use case,
it's more than fast enough, and doesn't copy any data.

If you think that's the same thing as parsing strings, you've completely missed
the point.


Well, forget about the missing/not missing the point.

My point is, there are various of reasons why we need different data
types in an RDBMS, just the same as why we need list, dict. There is
nothing stop me from using a list as dict(just scan it till I find it),
why would I I create a dict(your new view of the same data) ? Coding
convenience, speed or whatever.

If I need the dict feature 90% of the time, and the list feature 10% of
the time. I want an ordered dict. Rather than a list and create this
new view every time and every where I want to use it as a dict.

parsing or not parsing is not the point, and parsing/converting is
still "create a new view" of an existing data structure.

Nov 22 '05 #58

Fredrik Lundh wrote:
bo****@gmail.co m wrote:
Fredrik Lundh wrote:
but you can easily generate an index when you need it:

index = dict(d)

name, type = index["pid"]
print name

the index should take less than a microsecond to create, and since it
points to the members of the original dict, it doesn't use much memory
either...

Using the same logic, we don't need types other than string in a DBMS
as we can always convert a string field into some other types when it
is needed.


No, that's not the same logic. The dict() in my example doesn't convert be-
tween data types; it provides a new way to view an existing data structure.
There's no parsing involved, nor any type guessing. And given the use case,
it's more than fast enough, and doesn't copy any data.

If you think that's the same thing as parsing strings, you've completely missed
the point.


Well, forget about the missing/not missing the point.

My point is, there are various of reasons why we need different data
types in an RDBMS, just the same as why we need list, dict. There is
nothing stop me from using a list as dict(just scan it till I find it),
why would I I create a dict(your new view of the same data) ? Coding
convenience, speed or whatever.

If I need the dict feature 90% of the time, and the list feature 10% of
the time. I want an ordered dict. Rather than a list and create this
new view every time and every where I want to use it as a dict.

parsing or not parsing is not the point, and parsing/converting is
still "create a new view" of an existing data structure.

Nov 22 '05 #59
bo****@gmail.co m wrote:
If I need the dict feature 90% of the time, and the list feature 10% of
the time.
Wasn't your use case that you wanted to specify form fields in
a given order (LIST), render a default view of the form in that
order (LIST), and, later on, access the field specifiers in an
arbitrary order, based on their key (DICT). Sure looks like it's
the LIST aspect that's important here...

("but assume that I have some other use case" isn't a valid use
case)
I want an ordered dict. Rather than a list and create this new view every
time and every where I want to use it as a dict.
You want an ordered dict because you say you want one, not be-
cause it's the best way to address your use case. That's fine, but
it's not really related to the question asked in the subject line.
parsing or not parsing is not the point, and parsing/converting is
still "create a new view" of an existing data structure.


Copying the entire data structure hardly qualifies as "creating a
new view". dict() doesn't do that; in this use case, it doesn't cost
you anything to use it.

Everything has a cost in Python. Things aren't free just because
they're implemented by some other module.

But when things are free, they're often a good choice.

</F>

Nov 22 '05 #60

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

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.