how to merge lists in list (without numpy) - python

This is what i have-
def merge_list(mylist)
list1 = []
one_len = len(mylist)
two_len = len(mylist[0][0])
for index in range(two_len):
combine_list = []
for index2 in range(one_len):
combine_list.extend([a[index] for a in mylist[
index2]])
list1.append(combine_list)
return list1
But i have a problem with the output-
for example:
input-
mylist=[[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]], [[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]], [[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]]]
in short-
[[[1]*3]*4, [[2]*3]*4, [[3]*3]*4]
the output is -
[[[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]]]
and not -
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]]]
in short-
[[[1, 2, 3]]*3]*4
I would be happy to solve the problem and advise how to shorten the code.

In order to fix your code, you just need to update the return statement like this:
return [list1]
Though there is still a hidden problem when your inner lists lengths are longer than one element. Check your outputs with sample inputs like [[[2,1], [3,1]]].
One further - more compact - solution may be obtained by concatenating the inner lists within a cycle, then recreate the number of dimensions you need, moving the complexity from O(n^2) to O(n).
mylist = [[[2,1]],[[3,1]]]
def merge_list(mylist):
l_out = []
for l in mylist:
l_out += l[0]
return [[l_out]]
EDIT: In case of more complex inputs, you can extract first all elements and eventually fix the dimensions. This will still bring O(n^2) complexity though:
def merge_list(lst):
elements = [[] for _ in range(len(mylist[0]))]
for l1 in mylist:
for idx, l2 in enumerate(l1):
elements[idx] += l2
return [elements]
merge_list(mylist)
Input:
[[[1], [1]], [[2], [2]], [[3], [3]]]
Output:
[[[1, 2, 3], [1, 2, 3]]]

Related

difference in product using two different ways in python

I am experiencing a weird issue in finding the product of some numbers in two different ways. Example below. Can someone explain why the first method is not giving the correct answer?
Method 1:
arr = [[1, 2, 3]]*34
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
np.prod([len(x) for x in arr])
-217042295
Method 2:
pr = 1
for x in arr: pr = pr*len(x)
pr
16677181699666569
Thank you.
This happens because your numpy (I assume np is short for numpy) uses 32-bit integers.
That happens either because that is somehow the default for your computer, or because you configured numpy to use int32 as the default dtype for these operations. You can manually control this by providing np.prod with dtype=np.int64 to get the correct result.
>>> import numpy as np
>>> arr = [[1,2,3]] * 34
>>> np.prod([len(x) for x in arr], dtype=np.int32)
-217042295
>>> np.prod([len(x) for x in arr], dtype=np.int64)
16677181699666569
>>>

How to combine lists in list accordingly. (without numpy)

I have list of lists of lists and need to combine the inner lists accordingly.
For example:
1. mylist=[[[1]], [[2]]]
2.
mylist= [[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
[[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]],
[[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]]]
(in short-[[[1]*3]*4, [[2]*3]*4, [[3]*3]*4])
Expected output-
[[[1, 2]]]
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]]
(in short-[[[1, 2, 3]]*3]*4)
This is what I have untill now-
def combine_channels(mylist):
elements = [[] for _ in range(len(mylist[0]))]
for l1 in mylist:
for idx, l2 in enumerate(l1):
elements[idx] += l2
return [elements]
The problem is that the output is (for input example 2)-
[[[1, 1, 1, 2, 2, 2, 3, 3, 3],
[1, 1, 1, 2, 2, 2, 3, 3, 3],
[1, 1, 1, 2, 2, 2, 3, 3, 3],
[1, 1, 1, 2, 2, 2, 3, 3, 3]]]
and not-
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]]
mylist = [[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
[[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]],
[[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]]]
def combine_channels(mylist):
def list_zip(_list):
return list(zip(*_list))
elements = []
for l in list_zip(mylist):
elements.append(list_zip(l))
return elements
combine_channels(mylist)

How to reorder a list composed of lists

I am trying to tranform
[[1, 2, 3], [1, 2]]
into
[[1, 2, 3], [3, 2, 1], [2, 3, 1], [1, 2], [2, 1]]
But instead of the correct output, I am getting this:
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2], [1, 2]]
Here is my code
def listReorder(list1):
List2 = []
for list in list1:
listTemp = list
for item in list:
List2.append(listTemp)
t=listTemp.pop()
listTemp.insert(0, t)
return List2
List = [[1, 2, 3], [1, 2]]
listReorder(List)
In your for loop, you are adding the same list again and again, but instead, you should make a copy of the list in the iteration.
def listReorder(list1):
List2 = []
for list in list1:
listTemp = list
for item in list:
List2.append([x for x in listTemp])
t=listTemp.pop()
listTemp.insert(0, t)
return List2
List = [[1, 2, 3], [1, 2]]
listReorder(List)
Output:
[[1, 2, 3], [3, 1, 2], [2, 3, 1], [1, 2], [2, 1]]

Python recursive function wont change list defined in main()

Here I wrote a recursive function to find the permutation of a list.
def backtrack(arr,tmp):
if len(tmp)==len(arr):
res.append(tmp)
#==print res here==
print(res)
else:
for i in range(len(arr)):
if arr[i] in tmp: continue
tmp.append(arr[i])
backtrack(arr,tmp)
tmp.pop()
if __name__ == '__main__':
points=[1,2,3]
res=[]
tmp=[]
backtrack(points,tmp)
print(res)
#code result
#[[1, 3, 2], [1, 3, 2]]
#[[2, 1, 3], [2, 1, 3], [2, 1, 3]]
#[[2, 3, 1], [2, 3, 1], [2, 3, 1], [2, 3, 1]]
#[[3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2]]
#[[3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1]]
#[[], [], [], [], [], []]
I have no idea why the list 'res' defined in main() wont be updated when we pass it to a recursive function. Any suggestion about how to update 'res'?
When you do:
res.append(tmp)
you are appending to the global list res a reference to the list tmp. Any future changes to tmp will be visible through res as it just contains multiple references to the same tmp list.
Instead you probably want to append a copy of tmp:
res.append(list(tmp))
Make that change and your output is now:
[[1, 2, 3]]
[[1, 2, 3], [1, 3, 2]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
Alternatively you could convert the tmp list into a tuple:
res.append(tuple(tmp))
If you do that the option is then identical to the output returned by itertools.permutations:
>>> import itertools
>>> list(itertools.permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

generate all k-Permutations from n+1 without recalculate the k-permutations from n python 3

My task is to calculate the k-permutations from the updated List by new element
without recalculating the k-permutations already gotten from the previous state of the list. Example:
liste = [1, 2, 3]
3-permutations are:
[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
The updated list:
liste = [1, 2, 3, 4]
I would like to obtain directly 3-permutations[1, 2, 3, 4]-3-permutations[1, 2, 3]
without recalculating 3-permutations[1, 2, 3]
Calculate directly the new permutations:
[1, 2, 4], [1, 3, 4], [1, 4, 2], [1, 4, 3], [2, 1, 4], [2, 3, 4], [2, 4, 1],
[2, 4, 3], [3, 1, 4], [3, 2, 4], [3, 4, 1], [3, 4, 2], [4, 1, 2], [4, 1, 3],
[4, 2, 1], [4, 2, 3], [4, 3, 1], [4, 3, 2]
Thanks
Computing first the cartesian product {0,1,2,3}x{0,1,2}x{0,1} and taking the nth element of list (1,2,3,4).
r=[]
for prd in itertools.product([[0,1,2,3],[0,1,2],[0,1]]):
l=[1,2,3,4]
r0=[]
for i in prd:
r0 += l[i]
del l[i]
r += r0
EDIT: original answer gives the 3-permutations of [1,2,3,4]
following command answers specifically to question, see how it can be generalized
[list(j) for i in itertools.combinations([1,2,3],2) for j in itertools.permutations(list(i)+[4])]
next case, maybe one of ?
[list(j) for i in itertools.combinations([1,2,3],2) for j in itertools.permutations(list(i)+[4,5])]
[list(j) for i in itertools.combinations([1,2,3,4],3) for j in itertools.permutations(list(i)+[4,5])]
try saving the existing permutations to a list, then do:
if newPermutation not in listOfExistingPermutations:
listOfExistingPermutations.append(newPermutation)
or something along those lines

Categories

Resources