4

I simply wanted to know if you could call a function whenever a list is changed (item added to it). If anything it would look like this:

def listchanged():
    print("The list has been changed!")

list = ["apples","bananas"]
listevent(list,listchanged)

And in the shell you would append an item to the list and it would print "The list has been changed!"

Thanks!

2
  • 3
    What exactly do you need this for? There might be a better way. E.g., do you want to record each change, or just find out whether the list has been changed since some earlier point in time? And what are the methods the list might get changed by? Commented Sep 24, 2019 at 12:51
  • Not automatically, no. You have to make this sort of thing yourself, make sure you only change the list using functions you made that notify event listeners. Commented Sep 24, 2019 at 12:59

3 Answers 3

9

You can subclass list to print when changing the list.

Here's an example:

class EventList(list):

    def __setitem__(self, key, value):
        super(EventList, self).__setitem__(key, value)
        print("The list has been changed!")

    def __delitem__(self, value):
        super(EventList, self).__delitem__(value)
        print("The list has been changed!")

    def __add__(self, value):
        super(EventList, self).__add__(value)
        print("The list has been changed!")

    def __iadd__(self, value):
        super(EventList, self).__iadd__(value)
        print("The list has been changed!")

    def append(self, value):
        super(EventList, self).append(value)
        print("The list has been changed!")

    def remove(self, value):
        super(EventList, self).remove(value)

l = EventList(["apples","bananas"])
l.append('test')

Prints:

The list has been changed!

OR

Just compare lists:

old_list = ["apples","bananas"]
new_list = ["apples","bananas"]
newer_list = ["apples","bananas", "oranges"]

old_list == new_list #true
old_list == newer_list #false

This would work with no subclass as == compares if the lists have the same elements in the same indicies not if they are exactly the same by id or hash (in lamens). Just save the old one in a variable, then when you want to check just use this. (note: this does not provide a way for the print to be automatically called. It's just another way)

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

Comments

0
def listchanged():
    print("The list has been changed!")

lt = ["apples","bananas"]


def listevent(lt):
    prev_len=len(lt)

    lt.append("grapes")

    new_len=len(lt)
    
    if(prev_len!=new_len):
          listchanged()
listevent(lt)

3 Comments

The question is vague, may be try to make it clearer.
It's not that vague, the answer is just "No." He doesn't want to change the list inside listevent, he wants listevent to get called whenever the list is changed (as an event listener). Doesn't exist in Python by default.
It's not a good idea to name a list list since this is the name of the type which you bury below the new definition.
0

I needed a container that can fire an event when a new item arrives, I've chosen deque and subclassed it this way:

In:

from collections  import  deque

class ArrivalDeque(deque):
    def append(self, value):
        super().append(value)
        return value
    
    def appendleft(self, value):
        super().appendleft(value)
        return value

    def extend(self, value):
        super().extend(value)
        return value
    
    def extendleft(self, value):
        super().extendleft(value)
        return value
    
pack = [66346.8, 45646.8, 89050.4, 67050.1]    

deq = ArrivalDeque([43253.8, 325325.2, 25425.2])
deq.extend(pack)

Out:

[66346.8, 45646.8, 89050.4, 67050.1]

Returns can be modified obviously, to call another function, or to tell length of iterable passed to extend() , for example.

P.S.: take note that sometimes doing this: deq.extend(reversed(pack)) might save the day.

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.