Traverse a list with another list

Viewed 92

I have two lists where the elements of list A are contained in elements of list B. Note the order in this example is fairly important.

A = ['pent', 'tri', 'rec', 'oct', 'hex']
B = ['triangle', 'rectangle', 'pentangle', 'hexagon', 'octagon']

I would like to traverse A and B and wherever A is found in B, add that to a dictionary and then add that to a dictionary.

d = {'prefix': a, 'shape':b}

l = [{'prefix': 'pent', 'shape':'pentangle'}, {'prefix':'tri' , 'shape':'triangle'}, {'prefix': 'rec', 'shape':'rectangle'},...]

I tried using the zip function, but I think that because B is unordered with respect to A, it doesn't work

dict_list = []
for i,j in zip(A,B):
    if i in j:
        d = {'prefix': i, 'shape':j}
        dict_list.append(d)

I know that I could just do something like "for i in A if i in B" but then I dont know the syntax to get the matching value into my dictionary.

I think this is a pretty basic question, I just haven't been able to get it to work. Should this work with zip? I suppose it's also possible to pre-populate prefix and then somehow use that to find shape, but again, I'm not sure the syntax. The lists I'm using are 1000+ records in some instances so I can't do this manually.

EDIT: I made a mistake in my example: the actual lists and strings I'm working with aren't all using prefixes. I'm not sure if a different method can just be subbed into these answers but I appreciate all the responses. The strings I'm looking to parse are urls and parts of urls. So A is full of 'NA1234' type strings and B is 'www.oops/NA1244/betterexample'.

2 Answers

You can use list comprehension. This might not be the most efficient method, but at least the syntax is easy to understand.

A = ['pent', 'tri', 'rec', 'oct', 'hex']
B = ['triangle', 'rectangle', 'pentangle', 'hexagon', 'octagon']

dict_list = [{'prefix': a, 'shape': b} for a in A for b in B if b.startswith(a)]

print(dict_list) # [{'prefix': 'pent', 'shape': 'pentangle'}, {'prefix': 'tri', 'shape': 'triangle'}, {'prefix': 'rec', 'shape': 'rectangle'}, {'prefix': 'oct', 'shape': 'octagon'}, {'prefix': 'hex', 'shape': 'hexagon'}]

You could try a list comprehension with a generator:

[{'prefix': x, 'shape': next(y for y in B if y.startswith(x))} for x in A]

Output:

[{'prefix': 'pent', 'shape': 'pentangle'},
 {'prefix': 'tri', 'shape': 'triangle'},
 {'prefix': 'rec', 'shape': 'rectangle'},
 {'prefix': 'oct', 'shape': 'octagon'},
 {'prefix': 'hex', 'shape': 'hexagon'}]

Or you could first sort B to be the same order as A:

B = sorted(B, key=lambda x: next(i for i, v in enumerate(A) if x.startswith(v)))

Then just zip:

[{'prefix': x, 'shape': y} for x, y in zip(A, B)]
Related