[Tutor] list of dicts <-> dict of lists?

Matthew Wood woodm1979 at gmail.com
Fri May 28 01:19:20 CEST 2010


#!/usr/bin/env python


Here's my best attempt.  I'm not sure if it's "simpler" than yours,
but for me it seems a bit cleaner.  Then again, I LOVE the zip
operator, and the '*' operator too.  :-)  Whenever I see a "transpose
this" type problem, I think zip.


y = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}

print y

old = [dict([(i, y[i][j]) for i in y.keys()])
                          for j in range(len(y[y.keys()[0]]))]
print old


keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(keys, column)])
                    for column in zip(* values)]

print new

print new == old

I BELIEVE there's some new cool features in 2.6 or maybe 3.0 where
non-simultaneous access to my_dict.keys() and my_dict.values() will
keep them "paired up", but I don't know the details.  If you skipped
the upper line (setting keys and values) you'd be accessing y.keys() 3
times (in this example).  I'm not sure if you're guaranteed to have
the order remain the same for all three accesses.  If that's the case,
I'd change the code to be:

# This line isn't necessary #keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(y.keys(), column)])
                    for column in zip(* y.values())]

or even

# This line isn't necessary #keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(y, column)])
                    for column in zip(* y.values())]


But since I'm a coward, and I'd like my code to run on older versions
of python too, I'd leave the initial step.
--

I enjoy haiku
but sometimes they don't make sense;
refrigerator?


On Thu, May 27, 2010 at 4:15 PM, David Perlman <dperlman at wisc.edu> wrote:
>
> Using the csv.DictReader and csv.DictWriter lets you read and write lists of dictionaries from files containing tabular data.  I have a system that naturally generates tabular data in the form of a dictionary of lists: the dictionary key is the name of the column, and then the value is a list which contains the data for that column.  Sort of like a spreadsheet.  I would like to use csv.DictWriter to write out this data but that requires a list of dicts.
>
> I can convert the dict of lists to a list of dicts, and thus make it compatible with csv.DictWriter, with the following ugly comprehensions:
>
> >>> y
> {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
> >>> [dict([(i,y[i][j]) for i in y.keys()]) for j in range(len(y[y.keys()[0]]))]
> [{'a': 1, 'c': 7, 'b': 4}, {'a': 2, 'c': 8, 'b': 5}, {'a': 3, 'c': 9, 'b': 6}]
>
> ...but I'm wondering if anyone knows of a more elegant way, perhaps something built-in suited for this purpose...
>
> I am aware that any solution will only work if the lists in the dict are all the same length.  :)
>
> Thanks!
>
>
> --
> -dave----------------------------------------------------------------
> "Pseudo-colored pictures of a person's brain lighting up are
> undoubtedly more persuasive than a pattern of squiggles produced by a
> polygraph.  That could be a big problem if the goal is to get to the
> truth."  -Dr. Steven Hyman, Harvard
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor


More information about the Tutor mailing list