1

I have 3 lvls deep list as follows:

parent = [
   [
      {'x': 1, 'y': 2},
      {'x': 3, 'y': 8},
      .
      .
      .
   ],
   [
      {'x': 8, 'y': 5},
      {'x': 9, 'y': 6},
      .
      .
      .
   ]
]

I am trying to use list comprehension to get all the x into a list and all the y into another list

I tried something like this: [gc for gc in [c for c in [p.get('x') for p in parent]]]

but the get('x') is still hitting a list instead of an element, mainly because of the most inner []. Any idea how to achieve this?

jpp
  • 159,742
  • 34
  • 281
  • 339
jscriptor
  • 775
  • 1
  • 11
  • 26

2 Answers2

1

You don't need list comprehensions here.

Here's a functional solution via operator.itemgetter and itertools.chain:

from itertools import chain
from operator import itemgetter

parent = [[{'x': 1, 'y': 2},
           {'x': 3, 'y': 8}],
          [{'x': 8, 'y': 5},
           {'x': 9, 'y': 6}]]

x, y = zip(*map(itemgetter('x', 'y'), chain.from_iterable(parent)))

print(x)  # (1, 3, 8, 9)
print(y)  # (2, 8, 5, 6)

You can, alternatively, use nested list comprehensions:

x = [i['x'] for L in parent for i in L]
y = [i['y'] for L in parent for i in L]

Notice the order of the nested comprehension is consistent with a regular for loop:

x = []
for L in parent:
    for i in L:
        x.append(i['x'])
jpp
  • 159,742
  • 34
  • 281
  • 339
  • Thanks a lot .. x = [i['x'] for L in parent for i in L] is what I needed. I need to figure out why I struggled with this. ... Thanks again – jscriptor Dec 13 '18 at 18:33
0

The list comprehensions you are looking for could be:

[ [c.get('x') for c in p] for p in parent]

But this should be flattened, so maybe you should do something like:

print reduce(
    lambda curr, acc: curr + acc, 
    [ [c.get('x') for c in p] for p in parent],
    []
)

Hope this helps.