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 list
s 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]