Home > Enterprise >  If B is a subset of A, remove B from a, with elements in the same order
If B is a subset of A, remove B from a, with elements in the same order

Time:08-26

lets suppose A = [1, 2, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3].

If B is a subset of A, say [2, 1, 3];

I want to remove B from A in the same order to get [1, 2, 3, 1, 2, 3, 1, 2, 3].

Here's the code I used:

_set = [
    1, 2, 3,
    1, 2, 3, 
    2, 1, 3, 
    1, 2, 3
]
subset = [2, 1, 3]

def remove_subset(_set, subset):
    for i in subset:
        _set.remove(i)
    return _set

print(remove_subset(_set, subset))

But it gives the output [1, 2, 3, 2, 1, 3, 1, 2, 3].

The expected output is: [1, 2, 3, 1, 2, 3, 1, 2, 3].

CodePudding user response:

As written, you're removing the individual elements without paying attention to the order they appear. It looks like you want to delete the elements of the subset only if they appear contiguously in the same order as they do in the subset.

Sadly, this is something Python lists won't do for you (there is no equivalent to str.replace that allows you to remove a fixed sequence wherever it occurs). So you're stuck finding the index where your subsequence occurs and deleting it from the list:

for i in range(len(lst)):  # Renamed set to lst, since it is a list, and to avoid shadowing set constructor
    if lst[i:i len(sublst)] == sublst:  # Renamed subset to sublst to match
        del lst[i:i len(sublst)]  # We found a place where the sublst begins, slice it out
        break

This only removes one copy (to avoid issues with mutating a list as you iterate over it, or considering how to handle it if the sublist can overlap itself in the main list).

Side-note: This (iterating over slices of a sequence) is basically the only circumstance in which iterating over sequence indices is the Pythonic solution (there are ways to avoid the unPythonic for i in range(len(lst)): involving enumerate and zip and iter and explicit sequence multiplication and star-unpacking, but they're so ugly it's not worth the bother).

CodePudding user response:

One way could be to convert your lists to strings and use the .replace method of strings -

a = [1, 2, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3]
b = [2, 1, 3]
str_a = ''.join(map(str, a))
str_b = ''.join(map(str, b))
str_a_b_removed = str_a.replace(str_b, '')
list(map(int, list(str_a_b_removed)))

Output

[1, 2, 3, 1, 2, 3, 1, 2, 3]
  • Related