3

I have a master list and then a whole bunch (100s) of sublists cherry-picked from the master list. However, over time items in the master list will be removed. I want to also remove those items from each of the sublists. I imagine having a list that is only pointers to the master list. As the pointer goes stale then the list gets smaller. The sublists are normally in objects not easily accessible at the point where the master list is edited. Is this possible?

master = ["first","last","middle","top","bottom","left","right","inside"]

sides = []
sides.append(master[2])
sides.append(master[3])
sides.append(master[4])

centre = []
centre.append(master[0])
centre.append(master[2])
centre.append(master[7])

print(master)
['first', 'last', 'middle', 'top', 'bottom', 'left', 'right', 'inside']
print(sides)
['middle', 'top', 'bottom']
print(centre)
['first', 'middle', 'inside']

master.remove("middle")

print(master)
['first', 'last', 'top', 'bottom', 'left', 'right', 'inside']
print(sides) # Ideal outcome
['top', 'bottom']
print(centre) # Ideal outcome
['first', 'inside']

4 Answers 4

2

You could use a custom class that subclasses list. This way you can tailor the behavior of .remove:

class Lists(list):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # logic here, for now using the whole passed list
        self.sides = self[:]
        self.center = self[:]

    def remove(self, obj):
        #  TODO catch ValueError that is raised if obj isn't in all of the lists
        super().remove(obj)
        self.sides.remove(obj)
        self.center.remove(obj)

   # probably overriding other methods from list, such as append, so 
   # an instance can be used directly to interact with the "master" list

my_lists = Lists(["first", "last", "middle", "top", "bottom", "left", "right", "inside"])

print(my_lists)
my_lists.remove('last')
print(my_lists)
print(my_lists.sides)
print(my_lists.center)

# ['first', 'last', 'middle', 'top', 'bottom', 'left', 'right', 'inside']
# ['first', 'middle', 'top', 'bottom', 'left', 'right', 'inside']
# ['first', 'middle', 'top', 'bottom', 'left', 'right', 'inside']
# ['first', 'middle', 'top', 'bottom', 'left', 'right', 'inside']

You could also better encapsulate .master if needed (as the in-code comment suggests).


However, you may want to rethink the problem and the approach you have chosen to solve it. There might be a better way than keeping sublists of the original list, and you should also keep in mind that .remove will raise an exception if you try to delete a non-existing element from the list.

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

7 Comments

Any reason to subclass list? You aren't using any of the methods or attributes provided by the list type.
@vaultah 1. I'm overriding remove. 2. OP can override append as well to append to .master directly instead of my_lists.master.append.
I suppose i could create an array of lists in this, have a function for adding the sublists to the array and loop through them to do the remove.
You created a new attribute master instead of adding the elements from the master argument to the instance of your subclass. You never use it, so the inheritance makes no sense. And what is the point of implementing append, when you have to get the contents of the list by the attribute anyway?
@vaultah, this is just an idea, not a copy-paste-into-production sort of answer, however I did edit it so subclassing makes a bit more sense
|
1

The list element needs to be removed for every list that it is in. All you need to do to implement this is -

print(master)
['first', 'last', 'middle', 'top', 'bottom', 'left', 'right', 'inside']
print(sides)
['middle', 'top', 'bottom']
print(centre)
['first', 'middle', 'inside']

master.remove("middle")
sides.remove("middle")
centre.remove("middle")

print(master)
['first', 'last', 'top', 'bottom', 'left', 'right', 'inside']
print(sides) # Ideal outcome
['top', 'bottom']
print(centre) # Ideal outcome
['first', 'inside']

1 Comment

That is obvious and I will change my question to make it more understandable.
1

I came up with a solution for your problem, but it doesn't answer your question since I didn't link the different lists.

Nevertheless, I propose you this function:

def del_item(item, *args) :
    for lst in args :
        if item in lst :
            lst.remove(item)

Then you just have to call this function with the item you want to pop out and the different lists that you want to check.

Hope this can be useful

Comments

0

As modifying lists wasn't possible programatically without an iterative step I think the problem is better answered using a database query rather than a list data structure. Thanks @DeepSpace for a good answer

Comments

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.