How to partition and rearrange list values using a set of lists in python?

Question:

The lists ‘v1’, ‘v2’, ‘v3’, and ‘v4’ are standard lists.

v1 = ['Elisa', 'Liza', 'Izabela', 'Elisabeth', 'Elizabeth', 'Lisa', 'Lizzy', 'Isabella', 'Isabelle', 'Isabela', 'Liz']
v2 = ['Abbey', 'Abbie', 'Abigail', 'Abby', 'Gail']
v3 = ['Jonathan', 'Jon', 'John', 'Jonny', 'Johnny', 'Nathan']
v4 = ['Alejandra','Alexandra','Alexis','Alya','Alexa','Lexi','Allie','Ally']

List ‘a’ is given as input:

a = ['Jonathan', 'Jim', 'Jennifer', 'Alya', 'Renee', 'Natasha', 'Phil', 'Lisa', 'Joe', 'Ana', 'Paul', 'Gail', 'Roderick', 'Patricia']

There will be always just one value from each standard list appearing anywhere in list ‘a’.
The expected output is a list that will have sets of values partitioned by values that are found in list ‘a’ from lists ‘v1’, ‘v2’, ‘v3’, ‘v4’. Position of these sets will be rearranged in the order of ‘v1’ value set -> ‘v2’ value set -> ‘v3’ value set -> ‘v4’ value set

Expected output

a_out = ['Lisa', 'Joe', 'Ana', 'Paul', 'Gail', 'Roderick', 'Patricia', 'Jonathan', 'Jim', 'Jennifer', 'Alya', 'Renee', 'Natasha', 'Phil']

Image for partition and set arrangement reference –

enter image description here

Example 2:

Input

a = ['Abby', 'Robin', 'Natasha', 'Frank', 'Ana', 'Jennifer', 'Elizabeth', 'Tanya', 'Jim', 'Will', 'Rob', 'Joe', 'Alexa', 'Roger', 'Adam', 'Paul', 'James', 'Kara', 'John', 'Jeff', 'Rick', 'Steve']

Expected output

a_out = ['Elizabeth', 'Tanya', 'Jim', 'Will', 'Rob', 'Joe', 'Abby', 'Robin', 'Natasha', 'Frank', 'Ana', 'Jennifer', 'John', 'Jeff', 'Rick', 'Steve', 'Alexa', 'Roger', 'Adam', 'Paul', 'James', 'Kara']

Image for partition and set arrangement reference –

enter image description here

How to obtain such results using python lists?

Asked By: Sanket

||

Answers:

Try:

tmp = {}
for i, lst in enumerate([v1, v2, v3, v4], 1):
    for w in lst:
        tmp[w] = i

a_new, last = [], 0
for i, w in enumerate(a):
    last = tmp.get(w, last)
    a_new.append(last)

print([w for w, _ in sorted(zip(a, a_new), key=lambda k: k[1])])

Prints:

['Lisa', 'Joe', 'Ana', 'Paul', 'Gail', 'Roderick', 'Patricia', 'Jonathan', 'Jim', 'Jennifer', 'Alya', 'Renee', 'Natasha', 'Phil']

Note: If the first name(s) is not found in v1/v2/v3 or v4 it is placed at the beginning of the output list.

Answered By: Andrej Kesely

Alternative implementation. The basic logic is you want to first find which elements of a are in v, then you find where each partition starts and ends, then construct a_out with these indexes.

v1 = ['Elisa', 'Liza', 'Izabela', 'Elisabeth', 'Elizabeth', 'Lisa', 'Lizzy', 'Isabella', 'Isabelle', 'Isabela', 'Liz']
v2 = ['Abbey', 'Abbie', 'Abigail', 'Abby', 'Gail']
v3 = ['Jonathan', 'Jon', 'John', 'Jonny', 'Johnny', 'Nathan']
v4 = ['Alejandra','Alexandra','Alexis','Alya','Alexa','Lexi','Allie','Ally']

a = ['Abby', 'Robin', 'Natasha', 'Frank', 'Ana', 'Jennifer', 'Elizabeth', 'Tanya', 'Jim', 'Will', 'Rob', 'Joe', 'Alexa', 'Roger', 'Adam', 'Paul', 'James', 'Kara', 'John', 'Jeff', 'Rick', 'Steve']

a_set, v_contains = set(a), []

for lst in [v1, v2, v3, v4]:
    v_contains += [val for val in lst if val in a_set]

v_contains_set, v_contains_index, a_out = set(v_contains), [a.index(partition_start) for partition_start in v_contains], []

for idx in v_contains_index:
    if max(v_contains_index) != idx:
        a_out += a[idx:min(filter(lambda i: i > idx, v_contains_index))]
    else:
        a_out += a[idx:]

print(a_out)
Answered By: JRose
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.