Home > Software engineering >  Append elem to a list replace all list element to the last item I append
Append elem to a list replace all list element to the last item I append

Time:10-12

I'm trying to fight really strange behaviour. I'm reading radio frames at my raspberry pi and each frame that I receive I append to the list. I noticed that appending specific element cause replacing all list elements to this specific one.

Code is really simple:

    frames_radio_stats = []

    def radio_read():
        global frames_radio_stats 
        recv_buffer = []
        while True:
            if GPIO.wait_for_edge(17, GPIO.FALLING, timeout=3000):
                recv_buffer.clear()
                Radio.read(recv_buffer)
                if recv_buffer[0] == 144:
                    frames_radio_stats.append(recv_buffer)
                    print(recv_buffer)
                    print(frames_radio_stats)

prints outputs of first 2 elements looks like:

 [144, 55, 201, 226, 0, 0, 160, 131, 240]
[[144, 55, 201, 226, 0, 0, 160, 131, 240]]
 [144, 25, 96, 100, 147, 0, 96, 131, 84]
[[144, 25, 96, 100, 147, 0, 96, 131, 84], [144, 25, 96, 100, 147, 0, 96, 131, 84]]

As we see I get different frames (1 and 3 lines) but at the end all list is replaced with last elem. I also tried with "insert" elem instead of "append" but result was same.

Am I missing something?

CodePudding user response:

You are just appending references to the same list over and over again. Each .clear() clears the one list.

There are two options. The first is slightly better where you make a new list each time. The second is to have one list, but to save a copy of it each time:

frames_radio_stats = []

def radio_read():
    while True:
        if GPIO.wait_for_edge(17, GPIO.FALLING, timeout=3000):
            recv_buffer = []
            Radio.read(recv_buffer)
            if recv_buffer[0] == 144:
                frames_radio_stats.append(recv_buffer)
                print(recv_buffer)
                print(frames_radio_stats)

or

frames_radio_stats = []

def radio_read():
    recv_buffer = []
    while True:
        if GPIO.wait_for_edge(17, GPIO.FALLING, timeout=3000):
            recv_buffer.clear()
            Radio.read(recv_buffer)
            if recv_buffer[0] == 144:
                frames_radio_stats.append(recv_buffer[:])
                print(recv_buffer)
                print(frames_radio_stats)
  • Related