0

lets say I have a list:

A = ['x', 'y', 'z']

and another one - nested:

B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]

how can I remove 'z' from the last sublist in list B based on the knowledge that 'z' is in A and also every first element [0] of the sublist B is in list A ?

so basically i need to detele all elements from such a nested list where element is in A and where it not stands in the first position of that nested list ?

I am trying this but get stacked:

for i in B:
    for j in i[1:]:
        if j in A:
            del j

but I am missing something.

4
  • Why are you skipping the 0th element in i? Commented May 29, 2016 at 19:54
  • @IanAuld: from the question: and where it not stands in the first position of that nested list Commented May 29, 2016 at 19:55
  • Can you add expected output? I don't quite get where it not stands in the first position of that nested list, you seem to be ignoring all first elements Commented May 29, 2016 at 19:59
  • you can see it below in Martjin's answer. Commented May 29, 2016 at 20:21

2 Answers 2

1

You can use a nested list comprehension:

>>> [sub[:1]+[i for i in sub[1:] if not(sub[0] in A and i in A)] for sub in B]
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]

Here you'll preserve the items from sublists (from second item to end) that doesn't met your conditions for deleting.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, you could, but here I wouldn't. not (sub[0] in A and i in A) is not exactly rolling of the tongue.
@MartijnPieter Maybe, but sometimes it's cool to use double negative elimination in scripts :-).
1

Use a list comprehension to update a list in-place:

for sublist in B:
    if sublist[0] in A:
        sublist[1:] = [v for v in sublist[1:] if v not in A]

j in your loop is only another reference to a value in a sublist. del j removes that one reference, but the list still contains that reference. You can remove values from the list with del listobj[index] or listobj.pop(value) (watch for subtleties in what those mean), but deleting from a list while iterating over it will result in items being skipped if you are not careful.

By assigning to a slice, you replace those elements in the list itself, in-place.

Note that you probably want to make A a set; membership testing is far faster when using a set:

Aset = set(A)

for sublist in B:
    if sublist[0] in Aset:
        sublist[1:] = [v for v in sublist[1:] if v not in Aset]

Demo:

>>> A = ['x', 'y', 'z']
>>> B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]
>>> Aset = set(A)
>>> for sublist in B:
...     if sublist[0] in Aset:
...         sublist[1:] = [v for v in sublist[1:] if v not in Aset]
...
>>> B
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]

1 Comment

thank you, much appreciated. A was already a set but then I modified it again to list(A) because I thought playing with both list would be somehow easy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.