0

My ultimate goal is a function combining two nested lists, like this:

def tuples_maker(l1, l2):

    
    return sample_data

I know that I can use zip, but I don't know how to utilize "for" loop. I got stuck at first step then I cannot continue....

for example,

l1 = [[1,2,3,4], [10,11,12]]
l2 = [[-1,-2,-3,-4], [-10,-11,-12]]

I want something like this:

[[(1, -1), (2, -2), (3, -3), (4, -4)], [(10, -10), (11, -11), (12, -12)]]

On stack overflow I actually found a solution https://stackoverflow.com/a/13675517/12159353

print(list(zip(a,b) for a,b in zip(l1,l2)))

but it generates a iteration not a list:

[<zip object at 0x000002286F965208>, <zip object at 0x000002286F965AC8>]

so I try not to use list comprehension:

for a,b in zip(l1,l2):        
    c=list(zip(a,b))
print(c)

it is overlapped:

[(10, -10), (11, -11), (12, -12)]

I know this's not right but I still make a try:

for a,b in zip(l1,l2):        
    c=list(zip(a,b))
    print(c)

Now it seems right, but not a list:

[(1, -1), (2, -2), (3, -3), (4, -4)]
[(10, -10), (11, -11), (12, -12)]

Can anyone help me with this? Thanks in advance!

resssslll
  • 65
  • 1
  • 7
  • Change first `zip` to `list` or leave them as tuple: `list(zip(l1,l2))` for list of tuple or `list(list(x) for x in zip(l1,l2))` for list of lists. Follow the same for nested list in your example data – ThePyGuy Nov 13 '22 at 05:21
  • 1
    You almost did it with the list comprehension. Just misplaced the closing brace of `list`. `result = [ list(zip(a, b)) for a, b in zip(l1, l2) ]`, or `result = [ list(zip(*x)) for x in zip(l1, l2) ]`. – ILS Nov 13 '22 at 07:58

2 Answers2

2

Iterating the zip object yields a tuple of values, so you need to explicitly pass it to a list constructor if you want to create list out of those values

def combine_lists(l1,l2):
    return list([list(y) for y in zip(*x)] for x in zip(l1,l2))
   

OUTPUT

print(combine_lists(l1,l2))
#output
[[[1, -1], [2, -2], [3, -3], [4, -4]], [[10, -10], [11, -11], [12, -12]]]

UPDATE:

To get innermost pairs as tuple, just remove the innermost list constructor:

def combine_lists(l1,l2):
    return list([y for y in zip(*x)] for x in zip(l1,l2))
    
print(combine_lists(l1,l2))
#prints
[[(1, -1), (2, -2), (3, -3), (4, -4)], [(10, -10), (11, -11), (12, -12)]]
ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
2

In a list comprehension you can zip each sub-list separately like this:

l1 = [[1,2,3,4], [10,11,12]]
l2 = [[-1,-2,-3,-4], [-10,-11,-12]]

def sub_zip(l1, l2):
    return [list(zip(l1[i], l2[i])) for i in range(len(l1))]

sub_zip(l1, l2)

Output:

[[(1, -1), (2, -2), (3, -3), (4, -4)], [(10, -10), (11, -11), (12, -12)]]
D.Manasreh
  • 900
  • 1
  • 5
  • 9