nested lists in python - python

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.

(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]

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]

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)

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.

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.

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.

Related

Python: Replace duplicate values in a list with the same values

I have a list and would like to convert all duplicates values to 3 without changing the order and without importing any packages
X = [1, 2, 2, 5, 4, 8, 6]
Desired output:
X = [1, 3, 3, 5, 4, 8, 6]
This code automatically replace all duplicate items with 3
my_list = [1, 2, 2, 5, 4, 8, 6]
new = []
for item in my_list:
if my_list.count(item) > 1:
new.append(3)
else:
new.append(item)
print(new)
Among the fastest
fr = {x:0 for x in X}
for n in X:
fr[n] += 1
Y = [3 if fr[n]>1 else n for n in X]
You iterate over the list and add one to the dictionary counter for that number.
Then you create a list with list comprehension: you change the value to 3 if it is repeated more than once.
Little bit slower and little bit shorter
xi = {x:i for i, x in enumerate(X)}
dp = {x: xi[x]>i for i, x in reversed(list(enumerate(X)))}
Y = [3 if dp[x] else x for x in X]
You iterate over X and keep the lastest index of each value. Then you iterate again but in reverse order, and ask if there is another index for that value. Then with that info you create the desired output. All using list/dict comprehension. This is more of a functional approach.
Not sure why another user deleted their answer but that was a pretty simple one and uses basic list comprehension. So I am bringing the same to you. Please refer the code below for same:
X = [1, 2, 2, 5, 4, 8, 6]
print([3 if e==2 else e for e in X])
You should be able to use a for loop for this
my_list = [1, 2, 2, 5, 4, 8, 6]
new_list = []
for i in range(len(my_list)):
if my_list[i] in new_list:
new_list.append(3)
else:
new_list.append(my_list[i])
print(new_list)
Output:
[1, 3, 3, 5, 4, 8, 6]
Maybe something like this:
X = [t if t not in X[:i] + X[i+1:] else 3 for i, t in enumerate(X)]

creating a nested list from flat list with defined dimension

i have a flat list that i want to transform into nested list based on the defined dimension, the length of the flat list can be arbitrary, but the dimension should satisfy the length of the list, for example
[0,1,2,3,4,5,6,7]
will produce a nested list
m = 2
n = 4
[[0,1][2,3][4,5][6,7]]
or
m = 4
n = 2
[[0,1,2,3][4,5,6,7]]
i am thinking of using list comprehension to generate the nested list, but other option can also appending element from the flat list
a = [[i] * m for i in range(n)]
You can try this:
m = 2
n = 4
nums = [i*m for i in range(1,n+1)]
[list(range(x,y)) for x, y in zip([0] + nums, nums)]
OR
nums = [i*m for i in range(n)]
[list(range(z,z+m)) for z in (nums)]
Output:
[[0, 1], [2, 3], [4, 5], [6, 7]]
For
m = 4
n = 2
Output:
[[0, 1, 2, 3], [4, 5, 6, 7]]
Here's one option using list comprehensions:
col = list(range(10))
[
col[col.index(val):col.index(val) + m]
for val in col[::len(col)//n]
]

I want to split the sublists into its elements

import sys
su_pri=0
su_sc=0
n = int(raw_input().strip())
m=0
j=n-1
count=1
diff=0
a = []
for a_i in range(n):
a_temp = map(int,raw_input().strip().split(' '))
a.append(a_temp)
print a
while(m<=len(a)):
su_pri=sum(su_pri,int(a[m]))
m=m+n+1
while(count<=n):
su_sc=su_sc+a[j]
j=j+n-1
diff=abs(su_pri-su_sc)
print diff
if n=3 then the list is
3
11 2 4
4 5 6
10 8 -12
The list is
[[11, 2, 4], [4, 5, 6], [10, 8, -12]]
i want to store all elements into a single list with length=9(in this case)
How can i do that???
Please tell me
Create a new list and add them together
newdiff = []
for eachlist in diff:
newdiff += eachlist
print newdiff
I think you're looking to try to flatten a list of lists in python, which I found this post really helpful.
l = [[11, 2, 4], [4, 5, 6], [10, 8, -12]] #the list of lists to be flattened
flattenedList = [item for sublist in l for item in sublist]
For instance:
a = [[11, 2, 4], [4, 5, 6], [10, 8, -12]]
b = a[0] + a[1] + a[2]
You want to add each element in the array to each other. Something like this maybe? Hope that helps :)

How to add two nested lists in parallel and append result to a new list in python

I'm trying to add all the elements of two unequal nested lists in parallel and append the result back to another new list, i've written a little hacky code that could add them but there's a lot of things wrong with the code, first i tried to make the pairs equal by appending 0's to the end of the list but the code still runs into the problems since the length of the first pair is 3 and the length of the second pair is 4, i also tried using map but i couldn't add an integer and a NoneType,
import pdb
import itertools
x = [[2,3,3], [5,0,3]]
y = [[0,3], [2,3,3,3]]
for idx, (a, b) in enumerate(itertools.zip_longest(x, y)):
while len(a) < len(b):
x[idx].append(0)
while len(b) < len(a):
y[idx].append(0)
print(x, y)
new_list = list()
for i in zip(x, y):
for idx, j in enumerate(i):
for ind, a in enumerate(j):
val = x[idx][ind] + y[idx][ind]
new_list.append(val)
print(new_list)
the final result should be like this
[2, 6, 3, 7, 3, 6, 3]
You can simply use itertools.zip_longest and fill-in with 0, like this
>>> from itertools import zip_longest as zip
>>> x = [[2, 3, 3], [5, 0, 3]]
>>> y = [[0, 3], [2, 3, 3, 3]]
>>> [k + l for i, j in zip(x, y, fillvalue=[0]) for k, l in zip(i, j, fillvalue=0)]
[2, 6, 3, 7, 3, 6, 3]
This would would work even if x and y have unequal number of elements,
>>> from itertools import zip_longest as zip
>>> x = [[2, 3, 3], [5, 0, 3], [1]]
>>> y = [[0, 3], [2, 3, 3, 3]]
>>> [k + l for i, j in zip(x, y, fillvalue=[0]) for k, l in zip(i, j, fillvalue=0)]
[2, 6, 3, 7, 3, 6, 3, 1]
Note that, when we zip x and y, we use [0] as fillvalue. And when we zip i and j we use 0 as the fillvalue.
So, if the number of lists in x and y are not equal, then [0] will be used fill-in and when the number of elements in i and j are not equal, 0 will be used as the fill-in.
You can use fillvalue=0 in izip_longest to get ride of checking for validations then use map function for sum the zipped items:
from itertools import chain,zip_longest
list(chain.from_iterable(map(sum,zip_longest(i,j,fillvalue=0)) for i,j in zip_longest(x, y)))
[2, 6, 3, 7, 3, 6, 3]
Note that if you want to iterate over the result you don't have to use list (its just for demonstrating the result).
zip_longest is very helpful here:
x = [[2,3,3], [5,0,3]]
y = [[0,3], [2,3,3,3]]
from itertools import zip_longest
res = []
for list1, list2 in zip_longest(x, y, fillvalue=[0]):
for value1, value2 in zip_longest(list1, list2, fillvalue=0):
res.append(value1 + value2)
The fill value pads the list or sublist with the given value. In our case a new list with [0] for the outer loop and 0 for the inner loop.
Writing this a nested list comprehension does the same but may take more time to read and understand the code. Using more lines can make reading and understanding faster. Of course, this depends very much on the person reading the code.
from itertools import zip_longest
new_list = [a + b
for listpair in zip(x, y)
for a, b in zip_longest(*listpair, fillvalue=0)]

Solve folding paper challenge

Ok so I'm trying to solve this logical question in a pythonic way, but I'm not very good. Here goes:
You have a piece of paper with a list of numbers on it like so:
1 2 3 4 | 5 6 7 8
If you fold the paper from the left to the right down the middle, you get this order:
(first number is on top)
(4,5) (3,6) (2,7) (1,8)
And you can fold it one more time either way, and get a new order (right-to-left example):
(first number on top, then second below, ...etc)
(8,1,4,5) (7,2,3,6)
I started with seeing how to fold the paper and get a list of lists with the correct order:
paper = [1, 2, 3, 4, 5, 6, 7, 8]
half_paper = len(paper)/2
s = paper[:half_paper]
e = paper[half_paper:]
middle_distance = 0
final_list = []
for l in range(half_paper):
print l
m = [s[half_paper-middle_distance-1],e[middle_distance-half_paper]]
final_list.append(m)
middle_distance += 1
print final_list
This works, results in [[4,5], [3,6], [2,7], [1,8]] (fold left to right). But now I'm stuck. I've been trying to figure out a way to use list comprehension to apply the logic on the final_list result, so I can "fold" the paper again to get a result of [[5,4,1,8], [6,3,2,7]] (fold left to right again, or if fold right to left [[8,1,4,5], [7,2,3,6]]).
I'm not sure how to use list comprehension to do what i did in the for loop, on a list of lists and result in a list of lists. Any ideas to get me started?
l = [1, 2, 3, 4, 5, 6, 7, 8]
l1,l2 = l[:len(l)/2], l[len(l)/2:]
l = [ [x,y] for x,y in zip (l1, l2[::-1])]
for i in range(len(l)):
if isinstance(l[i][0], list):
l[i] = [x for item in l[i] for x in item]
print l
l1,l2 = l[:len(l)/2], l[len(l)/2:]
l = [ [x,y] for x,y in zip (l1, l2[::-1])]
for i in range(len(l)):
if isinstance(l[i][0], list):
l[i] = [x for item in l[i] for x in item]
print l
Output
[[1, 8], [2, 7], [3, 6], [4, 5]]
[[1, 8, 4, 5], [2, 7, 3, 6]]

Categories

Resources