0

Now I have a dictionary,

{2.9: [0.66], 3.3: [0.82, 0.48]}

and I want to flatten it to a tuple consisting of two lists:

([3.3, 3.3, 2.9], [0.82, 0.48, 0.66])

3.3 appears twice because there were two elements in the corresponding dictionary entry.

How do I do it?

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
Febday
  • 45
  • 5

4 Answers4

7

If tuple of tuples is ok, it's slightly simpler

>>> D = {2.9: [0.66], 3.3: [0.82, 0.48]}
>>> tuple(zip(*((k, v) for k in D for v in D[k])))
((3.3, 3.3, 2.9), (0.82, 0.48, 0.66))

If you really need lists

>>> tuple(map(list, zip(*((k, v) for k in D for v in D[k]))))
([3.3, 3.3, 2.9], [0.82, 0.48, 0.66])

My variation of @Steven's and @Padraic's answers. (I avoid using dict.items because it's behaviour is so different between Python2 and Python3)

keys, vals = result = [], []
for k in D:
    v = D[k]
    vals += v
    keys += [k] * len(v)
print(result)
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
2
>>> d = {2.9: [0.66], 3.3: [0.82, 0.48]}

First let's distribute the two keys of the dictionary into a list of tuples:

>>> ts = [(k, x) for k, l in d.items() for x in l]
>>> ts
[(3.3, 0.82), (3.3, 0.48), (2.9, 0.66)]

I'm using a two-level list comprehension, which is syntactic sugar for the equivalent nested loop.

Then you can transpose the list.

>>> result = zip(*ts)
>>> list(result)
[(3.3, 3.3, 2.9), (0.82, 0.48, 0.66)]

Or as a single expression, using a lazy generator expression instead of a list comprehension:

result = zip(*((k, x) for k, l in d.items() for x in l))
Community
  • 1
  • 1
Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
2

A variation of Stevens answer using extend as opposed to append as the dict keys are immutable so it is safe to just multiply.

d = {2.9: [0.66], 3.3: [0.82, 0.48]}

keys, vals = result = [], []
for k, v in d.items():
    vals.extend(v)
    keys.extend([k] * len(v))
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

The best answer is John La Rooy's one-liner using map, zip, and a generator expression. Here is a simplistic alternative:

d = {2.9: [0.66], 3.3: [0.82, 0.48]}

keys, vals = result = [], []
for k in d:
    for v in d[k]:
        keys.append(k)
        vals.append(v)
Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119