2

I have a zipped object like this:

z = zip(a, b)
lst = list(z)

print(lst)

Output:

[(0, array([[72, 65],
           [70, 71]], dtype=uint8)), 
(1, array([[ 71,  99],
           [190, 163]], dtype=uint8)), 
(2, array([[52, 59],
           [69, 72]], dtype=uint8)), etc...

I would like to flatten this list to the following:

[0, 72, 65, 70, 71, 1, 71, 99, 190, 163, 2, 52, 59 etc..]

I've tried doing this with

y = sum(w, ())
# or 
y = list(itertools.chain(*lst))

But the arrays are still there when I print.

What am I doing wrong?

pepe
  • 9,799
  • 25
  • 110
  • 188

3 Answers3

5

Use one of

Here is a MWE.

import numpy as np

lists = [(0, np.array([ [72,  65],
                        [70,  71]], dtype=np.uint8)), 
        (1, np.array([  [71,  99],
                        [190, 163]], dtype=np.uint8))]

l = list()
for idx, array in lists:
    l.append(idx)
    l.extend(np.ravel(array))   # returns a contiguous flattened array
    #l.extend(array.flat)       # return a 1-D iterator over the array.
    #l.extend(array.flatten())  # return a copy of the array collapsed into one dimension 

print(l)
# Output
[0, 72, 65, 70, 71, 1, 71, 99, 190, 163]

In speaking of the differences between ravel and flatten, excerpt from What is the difference between flatten and ravel functions in numpy?,

The difference is that flatten always returns a copy and ravel returns a view of the original array whenever possible. This isn't visible in the printed output, but if you modify the array returned by ravel, it may modify the entries in the original array. If you modify the entries in an array returned from flatten this will never happen. ravel will often be faster since no memory is copied, but you have to be more careful about modifying the array it returns.

Community
  • 1
  • 1
SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
3

You data is nested so you would need chain to recursively flatten which chain does not do, what you can do is flatten the numpy arrays and add:

from itertools import chain

print list(chain.from_iterable(([a] + arr.flatten().tolist()) for a, arr in lst))

Or use .flat and an inner chain:

print list(chain.from_iterable(chain([a],  arr.flat) for a, arr in lst))
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0
from itertools import chain
list(chain.from_iterable(chain([x], chain.from_iterable(y)) for x, y in z))

I'm using just chain for consistency but there are plenty of ways to flatten things, as @Padriac has shown.

Alex Hall
  • 34,833
  • 5
  • 57
  • 89