Search code examples
pythonlistdata-structureslist-comprehensionpython-itertools

How to create an alignment matrix given two lists


Given these two nested lists, which are the same. For example, from a_lis and b_lis are the same. However, list a is the reversed form of b_lis:

['Berries', 'grapes', 'lemon', 'Orange', 'Apple']

and

['Apple', 'Orange', 'lemon', 'grapes', 'Berries']

a_lis, and b_lis:

a_lis = [['Berries', 'grapes', 'lemon', 'Orange', 'Apple'],
 ['Apricots', 'peach', 'grapes', 'lemon', 'Orange', 'Apple'],
 [1, 'Melons', 'strawberries', 'lemon', 'Orange', 'Apple'],
 ['pumpkin', 'avocados', 'strawberries', 'lemon', 'Orange', 'Apple'],
 [3, 'Melons', 'strawberries', 'lemon', 'Orange', 'Apple']]

And

b_lis = [['Apple', 'Orange', 'lemon', 'grapes', 'Berries'],
 ['Apple', 'Orange', 'lemon', 'grapes', 'peach', 'Apricots'],
 ['Apple', 'Orange', 'lemon', 'strawberries', 'Melons', 1],
 ['Apple', 'Orange', 'lemon', 'strawberries', 'avocados', 'pumpkin'],
 ['Apple', 'Orange', 'lemon', 'strawberries', 'Melons', 3]]

How can I align them into a 2 dimensional nested list with all the possible alignments, if and only if the lists are different? For example, ['Berries', 'grapes', 'lemon', 'Orange', 'Apple'], and ['Apple', 'Orange', 'lemon', 'grapes', 'Berries'] should not be concatenated because they are the same (i.e. the first one is the reversed version from the other). This is how the expected output should look like this (*):

So far, I tried to first, create a function that tell me if two lists are the same no matter its position:

def sequences_contain_same_items(a, b):
    for item in a:
        try:
            i = b.index(item)
        except ValueError:
            return False
        b = b[:i] + b[i+1:]
    return not b

Then I iterated the lists:

lis= []
for f, b in zip(a_lis, b_lis):
    #print(f, b)
    lis.append(f)
    lis.append(b)
print(lis)

However, I do not get how to produce the alignment output list. What I do not understand is if product is the right operation to apply here. Any idea of how to produce (*)?


Solution

  • a_lis = [['Berries', 'grapes', 'lemon', 'Orange', 'Apple'],
     ['Apricots', 'peach', 'grapes', 'lemon', 'Orange', 'Apple'],
     [1, 'Melons', 'strawberries', 'lemon', 'Orange', 'Apple'],
     ['pumpkin', 'avocados', 'strawberries', 'lemon', 'Orange', 'Apple'],
     [3, 'Melons', 'strawberries', 'lemon', 'Orange', 'Apple']]
    reva = [k[-1::-1] for k in a_lis]
    
    m = [] 
    for i, v in enumerate(a_lis):
        for i1,v1 in enumerate(reva):   
            if i==i1:
                pass
            else:
                m.append(v)
                m.append(v1)
    print(m) 
    

    In a more compact way,

    m = sum([[v, v1] for i, v in enumerate(a_lis) for i1,v1 in enumerate(reva) if i!=i1], [])
    

    m = [[v, v1] for i, v in enumerate(a_lis) for i1,v1 in enumerate(reva) if i!=i1]