Dict to "flat" list of (key,value)
David C. Fox
davidcfox at post.harvard.edu
Wed Jul 30 16:38:11 EDT 2003
Nicolas Girard wrote:
> Hi,
>
> Forgive me if the answer is trivial, but could you tell me how to achieve
> the following:
>
> {k1:[v1,v2],k2:v3,...} --> [[k1,v1],[k1,v2],[k2,v3],...]
>
> The subtle point (at least to me) is to "flatten" values that are lists.
Well, I can get you at least part way, but there is an ambiguity in your
original data structure which causes problems:
1. d.items() will get you
[(k1, [v1, v2]), (k2, v3), ...]
2. Now, you want to expand out the list elements where the second part
of each tuple is a list, which you can do with.
flatten = lambda u: map(lambda x: (u[0], x), u[1])
or, if the double lambda expression is confusing:
def flatten(u):
return map(lambda x: (u[0], x), u[1])
(I've used a tuple (u[0], x) instead of a list, because your [k1, vn]
are always pairs, but you can use a list if you prefer)
Then flatten will take the nested element
(k1, [v1, v2])
and convert it to a list of tuples
[(k1, v1), [k2, v2])]
3. You want to apply flatten to each element of d.items(), which you
can do with
lol = map(flatten, d.items())
which will give you a list of lists of tuples,
4. and then reduce that to a list of tuples with
reduce(operator.add, lol)
Unfortunately, this doesn't quite work with your example above, because
flatten won't work properly when applied to (k2, v3). If v3 is a
sequence, it will instead give you [(k2, v3[0]), (k2, v3[1]), ...],
which is probably not what you want (especially if v3 is a string - try
flatten manually and see what happens). If v3 is not a sequence, you'll
get a TypeError saying that argument 2 to map() must support iteration.
If you *know* that v3 will NEVER be a list, you can modify flatten to
handle the special case like so:
def flatten(u):
if isinstance(u[1], type([])):
return (u[1], [u[2]])
return map(lambda x: (u[0], x), u[1])
Alternatively, if you can modify how the initial dictionary is generated
to ensure that cases where a key has a single value always appear as
k2: [v3] instead of k2: v3, then you can use the steps above without
modification. This is probably better if it is feasible, because your
original data structure is inherently ambiguous unless you know that v3
will never be a list.
David
>
> Thanks in advance,
> Nicolas
>
>
>
> ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
> http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
> ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
More information about the Python-list
mailing list