user7190127
user7190127

Reputation:

Removing a sublist from a list

I have a list e.g. l1 = [1,2,3,4] and another list: l2 = [1,2,3,4,5,6,7,1,2,3,4]. I would like to check if l1 is a subset in l2 and if it is, then I want to delete these elements from l2 such that l2 would become [5,6,7,1,2,3,4], where indexes 0-3 have been removed.

Is there a pythonic way of doing this?

I tried this:

l1 = [1,2,3,4]
l2 = [1,2,3,4,5,6,7,1,2,3,4]
l3 = []
for i in l2:
    if i in l1:
        l3.append(i)
-> prints [5,6,7]

However I would like the output to be [5,6,7,1,2,3,4].

Upvotes: 0

Views: 2887

Answers (2)

Josh Smeaton
Josh Smeaton

Reputation: 48710

I'm not proud of this, and it's not pythonic, but I thought it might be a bit of fun to write. I've annotated the code to make it a little more obvious what's happening.

>>> import re
>>> from ast import literal_eval

>>> l1 = [1,2,3,4]
>>> l2 = [1,2,3,4,5,6,7,1,2,3,4]
>>> literal_eval(         # convert the string into a python collection
...    re.sub(            # use a regex as a replacement
...       str(l1)[1:-1],  # string of the list, without surrounding brackets
...       '',             # replace with empty
...       str(l2)[1:-1],  # string for replacement, again without brackets
...       count=1         # only replace the first match
...    ).strip(',')       # replace any preceeding or trailing commas
...     .strip()          # replace any preceeding or trailing whitespace
... )
(5, 6, 7, 1, 2, 3, 4)

The output here is a tuple, but you could wrap it in list() if that's what you really want. Again, I'm not proud of this, but it works at least for this simple case. Juanpa's solution is much more preferable to this.

Upvotes: 0

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95873

Well, here is a brute-force way. There are probably more efficient ways. If you expect to encounter a matching sublist early, the performance shouldn't be terrible.

>>> l1 = [1,2,3,4]
>>> l2 = [1,2,3,4,5,6,7,1,2,3,4]
>>> for i in range(0, len(l2), len(l1)):
...     if l2[i:len(l1)] == l1:
...         del l2[i:len(l1)]
...         break
...
>>> l1
[1, 2, 3, 4]
>>> l2
[5, 6, 7, 1, 2, 3, 4]
>>>

Or if you don't want to modify l2, you could do the following:

>>> l1 = [1,2,3,4]
>>> l2 = [1,2,3,4,5,6,7,1,2,3,4]
>>> for i in range(0, len(l2), len(l1)):
...     if l2[i:len(l1)] == l1:
...         break
...
>>> l2[:i] + l2[i+len(l1):]
[5, 6, 7, 1, 2, 3, 4]
>>>

Upvotes: 3

Related Questions