Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python 3: Plist as OrderedDict

58 views
Skip to first unread message

Gnarlodious

unread,
Feb 8, 2010, 11:02:30 PM2/8/10
to
I am trying to read a *.plist into Python 3's OrderedDict but can't
figure it out. Saying something like this:

from plistlib import readPlist
dict=readPlist('/path/file.plist')
--> arbitrarily ordered dictionary compared to the XML file

from collections import OrderedDict
OrderedDict(readPlist('/path/file.plist'))
--> essentially does the same thing as the previous
readPlist seems to do the scrambling, is this a non-implementation in
Python 3.1?

I "upgraded" to Py3 to have OrderedDict, so please don't say it is
impossible...

-- Gnarlie

Ben Finney

unread,
Feb 8, 2010, 11:17:23 PM2/8/10
to
Gnarlodious <gnarl...@gmail.com> writes:

> from plistlib import readPlist
> dict=readPlist('/path/file.plist')
> --> arbitrarily ordered dictionary compared to the XML file

Right. The items in a dict are unordered, and when serialised to a list
they will appear in an arbitrary, unpredictable order.

>>> foo = dict(
... [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])
>>> foo
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}

> from collections import OrderedDict
> OrderedDict(readPlist('/path/file.plist'))
> --> essentially does the same thing as the previous

Yes, because you are initialising an OrderedDict instance from a dict.
That accesses the dict items as an iterable, which of course is going to
retrieve the items in an arbitrary, unpredictable order.

>>> foo.items()
dict_items([('a', 1), ('c', 3), ('b', 2), ('e', 5), ('d', 4)])

The OrderedDict then faithfully remembers the arbitrary ordering of the
items.

>>> from collections import OrderedDict
>>> OrderedDict(foo.items())
OrderedDict([('a', 1), ('c', 3), ('b', 2), ('e', 5), ('d', 4)])

> readPlist seems to do the scrambling

Nothing “does” the scrambling; the order is forgotten by the dict as
soon as the items go in.

> I "upgraded" to Py3 to have OrderedDict, so please don't say it is
> impossible...

What you'll need to do is insert the items into the OrderedDict instance
in the desired order. You will, of course, need to define what that
desired order is.

>>> sorted(foo.items(), key=(lambda item: item[0]))
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
>>> OrderedDict(sorted(foo.items(), key=(lambda item: item[0])))
OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])

--
\ “When we talk to God, we're praying. When God talks to us, |
`\ we're schizophrenic.” —Jane Wagner, via Lily Tomlin, 1985 |
_o__) |
Ben Finney

Benjamin Kaplan

unread,
Feb 8, 2010, 11:21:13 PM2/8/10
to pytho...@python.org

readPlist returns a dict. That dict is unordered. Wrapping the call in
OrderedDict() doesn't suddenly make readPlist use an ordered dict
instead, it just takes the (unordered) dict and sticks it in a new
OrderedDict. I suppose you could dig into the plistlib source code and
change that to use the OrderedDict if you really need it.
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Terry Reedy

unread,
Feb 8, 2010, 11:47:20 PM2/8/10
to pytho...@python.org
On 2/8/2010 11:02 PM, Gnarlodious wrote:
> I am trying to read a *.plist into Python 3's OrderedDict but can't
> figure it out. Saying something like this:
>
> from plistlib import readPlist

As a general note, include a link or something when discussing a
relatively obscure module that seems not to even be listed in pypi.

> dict=readPlist('/path/file.plist')

Redefining a basic builtin name like 'dict' is usually a bad idea.

> --> arbitrarily ordered dictionary compared to the XML file
>
> from collections import OrderedDict
> OrderedDict(readPlist('/path/file.plist'))
> --> essentially does the same thing as the previous
> readPlist seems to do the scrambling, is this a non-implementation in
> Python 3.1?
>
> I "upgraded" to Py3 to have OrderedDict, so please don't say it is
> impossible...

I agree with Benjamin -- check the source. Is plistlib 3.x ready?

Terry Jan Reedy

Ned Deily

unread,
Feb 9, 2010, 1:47:25 AM2/9/10
to pytho...@python.org
In article <hkqpci$f7l$1...@ger.gmane.org>, Terry Reedy <tjr...@udel.edu>
wrote:

> On 2/8/2010 11:02 PM, Gnarlodious wrote:
> > I am trying to read a *.plist into Python 3's OrderedDict but can't
> > figure it out. Saying something like this:
> > from plistlib import readPlist
> As a general note, include a link or something when discussing a
> relatively obscure module that seems not to even be listed in pypi.

http://docs.python.org/library/plistlib.html

--
Ned Deily,
n...@acm.org

Raymond Hettinger

unread,
Feb 9, 2010, 2:15:57 AM2/9/10
to
On Feb 8, 8:02 pm, Gnarlodious <gnarlodi...@gmail.com> wrote:
> I am trying to read a *.plist into Python 3's OrderedDict but can't
> figure it out. Saying something like this:
...

> I "upgraded" to Py3 to have OrderedDict, so please don't say it is
> impossible...

You may be able to monkey patch an OrderedDict into the PlistParser.
Here's an untested stab at it:

from collections import OrderedDict
import plistlib
plistlib._InteralDict = OrderedDict

Raymond


Message has been deleted

Gnarlodious

unread,
Feb 9, 2010, 11:07:42 AM2/9/10
to
On Feb 9, 12:15 am, Raymond Hettinger wrote:

> You may be able to monkey patch an OrderedDict into the PlistParser.
> Here's an untested stab at it:
>     from collections import OrderedDict
>     import plistlib
>     plistlib._InteralDict = OrderedDict


Genius! After fixing the misspelled InteralDict I got this:

from collections import OrderedDict
import plistlib

plistlib._InternalDict = OrderedDict
plistlib.readPlist('/path/to/some.plist')
--> OrderedDict([('List', 'of'), ('tuples', 'in'), ('plist',
'order')])

So thank you for that [somewhat contorted] solution.
To extract the list I am saying this:

ordered=plistlib.readPlist(path)
print(list(ordered)) # only a list of keys
print(ordered[list(ordered)[0]])

However this seems too laborious. is there an easier way?

-- Gnarlie

0 new messages