Adding elements from a list in a nested list - Python - python

I am using Python 3.6 and Django 1.11. I have a nested list -
nestedList = [[a, b, c], [d, e, f], [g, h, i]]
and another list -
newList = [1,2,3]
I need to club these and want a final list -
finalList = [[a, b, c, 1], [d, e, f, 2], [g, h, i, 3]]
Please let me know how this can be done.

just zip both lists together and create a new sublist:
nestedlist = [[1,2,3],[4,5,6],[7,8,9]]
newlist = [10,11,12]
result = [a+[x] for a,x in zip(nestedlist,newlist)]
print(result)
result:
[[1, 2, 3, 10], [4, 5, 6, 11], [7, 8, 9, 12]]

You can try:
>>> nestedList = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
>>> newList = [1,2,3]
>>>
>>> for num in range(len(newList)):
nestedList[num].append(newList[num])
>>> print nestedList
[['a', 'b', 'c', 1], ['d', 'e', 'f', 2], ['g', 'h', 'i', 3]]

For education purpose, a solution with recursion. Do not use in productive code.
nestedList = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
newList = [1,2,3]
def appendto(L1, L2):
if L1 == []:
return []
else:
return [L1[0] + [L2[0]]] + appendto(L1[1:], L2[1:])
print(appendto(nestedList, newList))
# -> [['a', 'b', 'c', 1], ['d', 'e', 'f', 2], ['g', 'h', 'i', 3]]

Related

How to split a nested list into multiple nested lists?

I have a nested list shaped like
mylist = [[a, b, c, d], [e, f, g, h], [i, j, k, l]]
And i need to split the nested lists so that every two items are grouped together like this:
Nested_list = [[[a, b], [c, d], [[e, f], [g, h]], [[i, j], [k, l]]
I tried splitting them by them by usinga for loop that appended them but this doesn't work.
mylist = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
nested_list = [ [i[:2], i[2:]] for i in mylist ]
print(nested_list)
Output:
[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']], [['i', 'j'], ['k', 'l']]]
mylist = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
Nested_list = []
for x in mylist:
Nested_list.append(x[:2])
Nested_list.append(x[2:])
print(Nested_list)
Output: [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h'], ['i', 'j'], ['k', 'l']]
import numpy as np
Nested_list = np.array(mylist).reshape(-1,2,2)
output:
array([[['a', 'b'],
['c', 'd']],
[['e', 'f'],
['g', 'h']],
[['i', 'j'],
['k', 'l']]], dtype='<U1')
from itertools import *
my_list = chain.from_iterable(my_list)
def grouper(inputs, n):
iters = [iter(inputs)] * n
return zip_longest(*iters)
print(list(grouper(my_list, 2)))

Python: Replace element in list inside list of list, with value from another list in same

I have a list of lists in python in which I want to replace the first value of some lists with the first value of the list preceding it, but only for certain lists.
for i, x in enumerate(protected_rows):
k = protected_rows[i + 1]
dup_rows_indx = range(x + 2, k, 2) =
for j in dup_rows_indx:
try:
rows[j][0] = rows[j-1][0]
else:
continue
basically if my list was
rows = [[a, b, c], [d], [e, f, g, h, i], [j, k, l, m], [n], [o, p], [q, r, s], [t, u], [v, w, x]]
and protected_rows = [1, 4] I want the output to be
rows = [[a, b, c], [d], [e, f, g, h, i], [e, k, l, m], [n], [o, p], [o, r, s], [t, u], [t, w, x]]
Any help appreciated. Relatedly I also then want to remove rows[j-1] but I've completely failed at the first step. Thank you.
Just for clarification here my view on the sample you've provided:
rows = [
['a', 'b', 'c'],
['d'], # < protected row (index: 1)
['e', 'f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n'], # < protected row (index: 4)
['o', 'p'],
['q', 'r', 's'],
['t', 'u'],
['v', 'w', 'x']
]
My assumption is that [2, 5] should be [1, 4]. (If you don't want to adjust that then there's an easy fix.)
Now try
protected_rows = [1, 4]
indices = [-1] + protected_rows + [len(rows)]
for i_0, i_1 in zip(indices[:-1], indices[1:]):
for i in range(i_0 + 2, i_1, 2):
rows[i][0] = rows[i - 1][0]
or (if you want to stick with [2, 5])
protected_rows = [2, 5]
indices = [-1] + [i - 1 for i in protected_rows] + [len(rows)]
for i_0, i_1 in zip(indices[:-1], indices[1:]):
for i in range(i_0 + 2, i_1, 2):
rows[i][0] = rows[i - 1][0]
to get
rows = [
['a', 'b', 'c'],
['d'], # < protected row (index: 1)
['e', 'f', 'g', 'h', 'i'],
['e', 'k', 'l', 'm'], # < first item now 'e'
['n'], # < protected row (index: 4)
['o', 'p'],
['o', 'r', 's'], # < first item now 'o'
['t', 'u'],
['t', 'w', 'x'] # < first item now 't'
]
Is that what you are looking for?
Original Code:
The code is not reproducible, so I am making an example as I go. Suppose we have a list of lists of integers, and we want to replace the first element of each list with the first element of its predecessor, but only if the replacement candidate is an even number. Here's one way of doing this:
import copy
lst = [[1,2,3],[4,5,6],[7],[8,9,10],[11,12,13],[14,15]]
#create a copy to change.
lst2=copy.deepcopy(lst)
lst2
#iterate over both lists
for l,k in zip(lst, lst2[1:]):
#print (l,k)
if(k[0]%2==0):
k[0]=l[0]
print('====')
print(lst2)
# Out:
# [[1, 2, 3], [1, 5, 6], [7], [7, 9, 10], [11, 12, 13], [11, 15]]
Edit As per Comment- See Below
If, on the other hand, you want to filter alterable lists based on a list of protected indices, then it can be done simply like this :
import copy
lst = [[1,2,3],[4,5,6],[7],[8,9,10],[11,12,13],[14,15]]
protected_rows= [2,4]
#create a copy to change.
lst2=copy.deepcopy(lst)
#start counting from 1, include final index
for i in range(1,len(lst)):
if(i not in protected_rows ):
lst2[i][0]=lst2[i-1][0]
print(lst)
#print(protected_rows)
print(lst2)
#out:
# [[1, 2, 3], [4, 5, 6], [7], [8, 9, 10], [11, 12, 13], [14, 15]]
# [[1, 2, 3], [1, 5, 6], [7], [7, 9, 10], [11, 12, 13], [11, 15]]
Note: If we don't use a copy , the changes will cascade, i.e. the elements will be replaced by the altered value in previous list.
You can try this:
rows = [['a', 'b', 'c'], ['d'], ['e', 'f', 'g', 'h', 'i'], ['j', 'k', 'l', 'm'], ['n'], ['o', 'p'], ['q', 'r', 's'], ['t', 'u'], ['v', 'w', 'x']]
protected_rows = [2, 5]
for i in range(len(rows)):
for j in range(len(protected_rows)):
if i == protected_rows[j]:
rows[i+1][0] = rows[i][0]
for the rows[j-1] part please explain in more detail what you need.
output:
[['a', 'b', 'c'], ['d'], ['e', 'f', 'g', 'h', 'i'], ['e', 'k', 'l', 'm'], ['n'], ['o', 'p'], ['o', 'r', 's'], ['t', 'u'], ['v', 'w', 'x']]

Replace the third element of all sublists with another list

I have a list of lists and I want to replace/update the third element of all the sublists with a new list.
lst1 = [['a','b','c', 3],['d','e','f', 9],['g','h','i', 'j']]
lst2 = [2, 3, 4]
Desired output:
lst_new = [['a','b', 2, 3],['d','e', 3, 9],['g','h', 4, 'j']]
Try this:
lst1 = [['a','b','c', 3],['d','e','f', 9],['g','h','i', 'j']]
lst2 = [2, 3, 4]
for x,y in zip(lst1,lst2): #loops over both lst1 and lst2
x[2] = y
output:
[['a', 'b', 2, 3], ['d', 'e', 3, 9], ['g', 'h', 4, 'j']]
Can you use numpy? As simple as:
arr1 = np.array(lst1)
arr1[:, 2] = lst2
Output:
array([['a', 'b', '2', '3'],
['d', 'e', '3', '9'],
['g', 'h', '4', 'j']], dtype='<U1')
lst1 = [['a','b','c', 3],['d','e','f', 9],['g','h','i', 'j']]
lst2 = [2,3,4]
#We make a copy so that this 'lst_new' variable does not point to lst1
lst_new = lst1.copy()
for num, lst in zip(lst2, lst_new):
lst[2] = num
#At this point, your lst_new will be changed
lst1 = [['a', 'b', 'c', 3], ['d', 'e', 'f', 9], ['g', 'h', 'i', 'j']]
lst2 = [2, 3, 4]
for x in range(0, len(lst2)):
lst1[x][2] = lst2[x]
print(lst1)
Just for the fun of having another option:
map(lambda e, subls: [*subls[:2], e, *subls[3:]], lst2, lst1))
It makes use of map, lambda and the unpacking operator *.

working with a list vs a list created by a function

I have the following list "mylist" for which i created "foundkeys" function to search it for occurrence of another list "keys" items , The output will look like "formatted_list" now i pass the output of "foundkeys" to "reorder" function which reorders the content of passed "order" example of "foundkeys" into specific format .
The problem
If i use the the above setup i don't get the exact output needed but if i pass '"formatted_list"' "which is the exact output of "foundkeys" ", to "reorder" instead of calling "foundkeys" , i would get the needed format
the correct output should be like this :
with 'a' key having its elements starting with 'a' and 'k' key having its elements starting with 'k'
[['a', [[1, 'a', 'Asfoor', 'b', 'c'],
[2, 'a', 'j', 'deek', 'k'],
[3, 'a', 'k', 'bata', 'p']]],
['k', [[2, 'k', 'j', 'a', 'deek'],
[3, 'k', 'bata', 'a', 'p'],
[4, 'k', 'v', 'm', 'farkha']]]]
but if i use the setup i get the this wrong output:
where it puts 'k' instead of 'a' in elements of of the 'a' key
[['a', [[1, 'a', 'Asfoor', 'b', 'c'],
[2, 'k', 'j', 'deek', 'a'],
[3, 'k', 'a', 'bata', 'p']]],
['k', [[2, 'k', 'j', 'deek', 'a'],
[3, 'k', 'a', 'bata', 'p'],
[4, 'k', 'v', 'm', 'farkha']]]]
kindly have a look into the code for better understanding.
mylist=
[[1, 'Asfoor', 'a', 'b', 'c'],
[2, 'deek', 'j', 'a', 'k'],
[3, 'bata', 'k', 'a', 'p'],
[4,'farkha','v','m','k']]
keys = ['a', 'k']
def foundkeys(mylist,keys):
def found(list, k):
return k in list
final = []
for j in keys:
final.append([j , [k for k in mylist if found(k, j)]])
return final;
order=foundkeys(mylist,keys)
print("New list with found keys \n",order)
formatted_list=
[
[
'a', [[1, 'Asfoor', 'a', 'b', 'c'], [2, 'deek', 'j', 'a', 'k'], [3, 'bata', 'k', 'a', 'p']
]],
[
'k', [[2, 'deek', 'j', 'a', 'k'], [3, 'bata', 'k', 'a', 'p'], [4, 'farkha', 'v', 'm', 'k']]
]
]
def reorder(alist):
for item in alist:
key=item[0]
value=item[1]
for c,v_item in enumerate(value):
old=value[c][1]
for i,s_value in enumerate(value[c]):
if s_value==key:
value[c][i]=old
value[c][1]=key
# calling reorder function with order function list
reorder(order)
print(order)
# calling reorder function with formatted_list instead
reorder(formatted_list)
print(formatted_list)
Python use references to store the lists. To see this, try running the following code.
a = [1, 2]
b = [a for i in range(0, 3)]
print(b) # prints out [[1, 2], [1, 2], [1, 2]]
b[0][0] = 4
print(b) # prints out [[4, 2], [4, 2], [4, 2]]
[a for i in range(0, 3)] does not insert three "individual" a into b. It actually insert a's reference into b. So when we change an element through b[0][0], we change all the lists with the same reference.
To solve this, just ask python to create a new list, not just copying the reference.
a = [1, 2]
b = [list(a) for i in range(0, 3)] # This line is different
print(b) # prints out [[1, 2], [1, 2], [1, 2]]
b[0][0] = 4
print(b) # prints out [[4, 2], [1, 2], [1, 2]]
So in your code, it should be
for j in keys:
final.append([j , [list(k) for k in mylist if found(k, j)]])
And now you will get the same result using order and formatted_list.
You can see this post for more understanding about references and copies.

Unpack a nested list

My question is simple.
There are two lists.
The first is a list of integers:
a = [1, 2, 3]
The other is a list of lists:
b = [['a', 'b'], ['c', 'd'], ['e', 'f']]
How could I get the result below:
result = [[1, 'a', 'b'], [2, 'c', 'd'], [3, 'e', 'f']]
Thanks.
>>> a = [1, 2, 3]
>>> b = [['a', 'b'], ['c', 'd'], ['e', 'f']]
>>> [[aa] + bb for aa, bb in zip(a, b)]
[[1, 'a', 'b'], [2, 'c', 'd'], [3, 'e', 'f']]
In Python3
>>> a = [1, 2, 3]
>>> b = [['a', 'b'], ['c', 'd'], ['e', 'f']]
>>> [aa+bb for *aa, bb in zip(a,b)]
[[1, 'a', 'b'], [2, 'c', 'd'], [3, 'e', 'f']]
Another way to do this would be:
index = 0
l = b
for i in a:
l[index].append(i)
index += 1
The following Python code will unpack each list and assemble it in the form you indicated.
[[a[i]] + b[i] for i in range(min(len(a),len(b)))]
Using Python's enumerate function you can loop over a list with an index. Using x.extend(y) will prepend the values in list x to list y.
a = [1, 2, 3]
b = [['a', 'b'], ['c', 'd'], ['e', 'f']]
result = []
for index, value in enumerate(a):
aa = [value]
aa.extend(b[index])
result.append(aa)

Categories