0

I am trying to split the following list:

A_list = [[[1,2,3,4],[5,6]],          ==>[0]
          [[3,4,5],[2,3,5]],          ==>[1]
          [[5,8,9],[10,11]],          ==>[2]
          [[22,20],[5,7,8]]]          ==>[3]

to:

 x_list = [[1,2,3,4],[5,6],
           [5,8,9],[10,11]]

 y_list = [[3,4,5],[2,3,5] ,
           [22,20],[5,7,8]]

x_list has row [0] , row [2] and row [4] ....

y_list has row [1] , row [3] and row [5] ...

where each row has 2 lists

is there any way to do that?

thank you for help or hints

I should mention that 'A_list' in this question has been modified. It was as below:

A_list = [[1,2,3,4],[5,6],          ==>[0]
      [3,4,5],[2,3,5],              ==>[1]
      [5,8,9],[10,11],              ==>[2]
      [22,20],[5,7,8]]              ==>[3]

most of the posted answers were to the question before editing. Thanks for all the helpful answers.

S.M
  • 71
  • 5
  • Your nested list does not have "rows". Instead, the first two elements go to one list, the third and fouth to another, etc. – tobias_k Jul 17 '17 at 11:42
  • so all even indexes go into x_list and all odd indexes go into y_list? – SuperShoot Jul 17 '17 at 11:44
  • yes, that what I'm trying to do – S.M Jul 17 '17 at 11:52
  • @S.M Since you modified your question the accepted answer became invalid. Could you please accept another answer which corresponds to the question as it is now? Thank you! – a_guest Jul 17 '17 at 13:33

6 Answers6

3

(This first part of this answer was written before the question was edited, changing the layout of A_list.) Your list does not have "rows". Instead, you want to assign the 1st and 2nd element to x_list, the 3rd and 4th to y_list, 5th and 6th to x_list again, and so on.

For this, you can enumerate the elements in your list and assign them to x_list and y_list based on their index modulo 4.

>>> x_list = [a for i, a in enumerate(A_list) if i % 4 < 2]
>>> x_list
[[1, 2, 3, 4], [5, 6], [5, 8, 9], [10, 11]]
>>> y_list = [a for i, a in enumerate(A_list) if i % 4 >= 2]
>>> y_list
[[3, 4, 5], [2, 3, 5], [22, 20], [5, 7, 8]]

Or, you could first create those rows by grouping the list in groups of two entries, and then using slice notation [::2] and [1::2] to extract the elements and flatten those lists again:

>>> rows = [A_list[i:i+2] for i in range(0, len(A_list), 2)]
>>> x_list = [x for g in rows[::2] for x in g]
>>> y_list = [y for g in rows[1::2] for y in g]

After you silently modified your question (Don't do that; you invalidated most existing answers!) you can now use my 2nd approach, except that your new A_list is now already what rows was there:

>>> x_list = [x for g in A_list[::2] for x in g]
>>> y_list = [y for g in A_list[1::2] for y in g]
tobias_k
  • 81,265
  • 12
  • 120
  • 179
2

You can use slicing syntax to extract the required items and then flatten the resulting sub-lists:

x_list = [item for sub in A_list[::2] for item in sub]
y_list = [item for sub in A_list[1::2] for item in sub]
a_guest
  • 34,165
  • 12
  • 64
  • 118
1

Contrary to Python TOOWTDI principle, there are several ways to do it. One possibility is:

x_list = [A_list[i] for i in range(len(A_list)) if i % 4 < 2]
y_list = [A_list[i] for i in range(len(A_list)) if i % 4 >= 2]

Another:

rows = [ A_list[i:i+4] for i in range(0, len(A_list), 4)]
x_list = [x for row in rows for x in row[0:2]]
y_list = [x for row in rows for x in row[2:4]]

Both the solutions above are for the original problem (before it was modified). For solutions to the problem as it stands now see here.

a_guest
  • 34,165
  • 12
  • 64
  • 118
Błotosmętek
  • 12,717
  • 19
  • 29
  • 1
    Alternative way: x_list, y_list = [i for ind,i in enumerate(A_list) if ind % 2 == 0],[i for ind,i in enumerate(A_list) if ind % 2 != 0] – Anton vBR Jul 17 '17 at 11:57
  • @AntonvBR the solution using `enumerate` was already shown by tobias_k, so I skipped it. – Błotosmętek Jul 17 '17 at 11:58
  • 1
    @Błotosmętek Please note that the question has been (silently) modified after you posted your answer - it doesn't answer the question anymore. – a_guest Jul 17 '17 at 13:15
  • @Błotosmętek What a mess :D Actually I could observe what happened, so the OP modified the question, then unaccepted your answer and then accepted it again. Maybe you could modify it, so it answers the question? Otherwise other people might get confused by the situation here. – a_guest Jul 17 '17 at 13:30
  • @a_guest It would be much better if the OP changed the accepted solution from mine to yours or the one by tobias_k. – Błotosmętek Jul 17 '17 at 13:32
1

Just a simple loop.

A_list = [[1,2,3,4],[5,6],[3,4,5],[2,3,5],[5,8,9],[10,11],[22,20],[5,7,8]]
x_list = []
y_list = []
V = 0
for A in A_list:
    if V % 4 < 2:
        x_list.append(A)
    else:
        y_list.append(A)
    V = V + 1

print(x_list, y_list)
0

If you are assuming that there are only two columns in each row then you can do something like this:

A_list = [[1,2,3,4],[5,6],
      [3,4,5],[2,3,5],
      [5,8,9],[10,11],
      [22,20],[5,7,8]]

x_list = []
y_list = []

for x in range(len(A_list))[::4]:
    x_list.append(A_list[x])
    x_list.append(A_list[x + 1])
    y_list.append(A_list[x + 2])
    y_list.append(A_list[x + 3])

Note: This only works if the number of columns is two. If the number of columns is not always two or another set number this is a difficult task as the Python list

 x_list = [[1,2,3,4],[5,6],
       [5,8,9],[10,11]]

Is the same as

 x_list = [[1,2,3,4],[5,6],[5,8,9],[10,11]]

This will work for any amount of inputs.

Jude Molloy
  • 193
  • 3
  • 18
-1

You can achieve this with slicing alone and no conditionals like so:

A_list = [[1,2,3,4],[5,6],
          [3,4,5],[2,3,5],
          [5,8,9],[10,11],
          [22,20],[5,7,8]]

x_list = A_list[::4] + A_list[1::4]
y_list = A_list[2::4] + A_list[3::4]
print(x_list)  # [[1, 2, 3, 4], [5, 8, 9], [5, 6], [10, 11]]
print(y_list)  # [[3, 4, 5], [22, 20], [2, 3, 5], [5, 7, 8]]

But it does not preserve the order. If that is important to you go with one of the other solutions posted.

Ma0
  • 15,057
  • 4
  • 35
  • 65
  • No, that's not what the OP wanted. – Błotosmętek Jul 17 '17 at 11:42
  • @Błotosmętek I guess I read it too fast.. Thanks for the head's up. – Ma0 Jul 17 '17 at 11:48
  • @Ev.Kounis It seems that the question has been modified so that the shape of `A_list` is different now. However I just wanted to comment on the ordering. If you want to preserve ordering then you could - instead of adding the sliced lists - `zip` them up and [flatten](https://stackoverflow.com/a/952952/3767239) the result: `[x for sub in zip(A_list[::4], A_list[1::4]) for x in sub]`. – a_guest Jul 17 '17 at 12:34
  • 1
    @a_guest there are a lot of things you can do to restore order but this solution probably stops being efficient if you go down that road. Another alternative for example would be this: `[x for x in A_list if x in A_list[::4] + A_list[1::4]]` which uses the order of the original `list` to order the new one. – Ma0 Jul 17 '17 at 12:41