Search code examples
pythonmergetupleslist-comprehensionnested-lists

Combine list of lists of tuples with different lengths


I'm having a problem to combine list of lists of tuples, and the main problem comes from different sizes of those tuples. I'm also trying to do it "pythonic" way, which isn't very easy.

What I actually have is a list of objects, having coordinates given in tuple. Objects (let's say: lines) always have start and end as (x1,y1) and (x2,y2), they also usually have some "path". The problem is that "path" is sometimes empty and in general number of points on the path is different.

start=[ (3,5), (23,50), (5,12), (51,33), (43,1)]
end = [(23,19), (7,2), (34,4),  (8,30), (20,10)]
path=[[(10,7),(14,9),(18,15)],
      [],
      [(15,7)],
      [(42,32),(20,31)],
      [(30,7)]]

Expected result should look like this:

whole_path = [[(3,5),(10,7),(14,9),(18,15),(23,19)],
              [(23,50),(7,2)],
              [(5,12),(15,7),(34,4)],
              [(51,33),(42,32),(20,31),(8,30)],
              [(43,1),(30,7),(20,10)]]

I was trying to use zip - it works well for similar size items in start/end/paths lists but not with their differences. Promising solutions might come with use path.insert(0,start) and path.extend([end]), but I couldn't make that working, there is also an option to put that into two loops, but it doesn't look well and... it's not very "pythonic". So: any suggestions would be nice.


Solution

  • A solution with zip and *-unpacking of the variable-length path element is reasonably clean:

    from pprint import pprint
    
    start=[ (3,5), (23,50), (5,12), (51,33), (43,1)]
    end = [(23,19), (7,2), (34,4),  (8,30), (20,10)]
    path=[[(10,7),(14,9),(18,15)],
          [],
          [(15,7)],
          [(42,32),(20,31)],
          [(30,7)]]
    
    whole_path = [[s, *p, e] for s, p, e in zip(start, path, end)]
    pprint(whole_path)
    

    giving the required:

    [[(3, 5), (10, 7), (14, 9), (18, 15), (23, 19)],
     [(23, 50), (7, 2)],
     [(5, 12), (15, 7), (34, 4)],
     [(51, 33), (42, 32), (20, 31), (8, 30)],
     [(43, 1), (30, 7), (20, 10)]]