简体   繁体   中英

How to set the value of a variable as the value of another variable thats a list in Python

I currently have a class, that has 2 attributes, initial_value , and current_value . Both are lists, and the initial value is set programmatically during run time, and is not always the same. They start off the same, but throughout the code, the current_value changes. I then need to reset it to the initial_value , but I am wondering the best way to do this without my code ever affecting the initial_value .

Here is what does not work due to the pointer changing to the same object as initial value :

class MyClass:
    def __init__(self,v1,v2,v3,v4,v5,v6):
        ## both initial value and current value get set as the same value during run time
        self.initial_value = [[v1,v2,v3],[v4,v5,v6]]
        self.current_value = [[v1,v2,v3],[v4,v5,v6]]

    def Reset(self):
        self.current_value = self.initial_value ### what is the best way to fix this?



myclass = MyClass(1,2,3,4,5,6)

# value of current_value will change throughout the program
myclass.current_value[0][0] = 5

# periodically, need to reset
myclass.Reset()

The challenge that I am having is that the Reset function gets called many many times, so I am trying to come up with the fastest way of achieving this result.

The best I could come up with so far is:

self.current_value = [*self.initial_value]

Being self taught, I just dont know what the most idiomatic, and efficient way of achieving this.

Thanks so much in advanced!

There are many options how to handle that. Myself, I would create get_init_values() method that returns initial values for a list:

class MyClass:
    def __init__(self):        
        # self.initial_value = self.get_init_values()  # now the initial value is not needed, all is handled by get_init_values()
        self.current_value = self.get_init_values()

    def get_init_values(self):
        return [[1,2,3],[4,5,6]]

    def Reset(self):
        self.current_value = self.get_init_values()

myclass = MyClass()

# value of current_value will change throughout the program
myclass.current_value[0][0] = 5

# periodically, need to reset
myclass.Reset()

EDIT: Updated for initial values in constructor:

class MyClass:
    def __init__(self,v1,v2,v3,v4,v5,v6):
        self.__values = [v1,v2,v3,v4,v5,v6]
        self.current_value = self.get_init_values()

    def get_init_values(self):
        return [self.__values[0:3], self.__values[3:6]]

    def Reset(self):
        self.current_value = self.get_init_values()



myclass = MyClass(1,2,3,4,5,6)

# value of current_value will change throughout the program
myclass.current_value[0][0] = 5

# periodically, need to reset
myclass.Reset()

print(myclass.current_value)

The problem is that lists are containers and assignment of containers creates a new reference to the existing container, not a new copy of the container. You have a container that contains other containers (a list of lists), which means that you have to make sure that you are copying all of the lists, not just the top level one. This is the reason that copy.deepcopy() exists.

import copy

class MyClass:
    ...

    def Reset(self):
        self.current_value=copy.deepcopy(self.initial_value)

As an alternative to copy.deepcopy() if you have a fixed structure for your items, for example, you know that they are always lists of lists, then you can use a list comprehension to create a copy:

    def Reset(self):
        self.current_value=[lst[:] for lst in self.initial_value]

Testing these two approaches shows that the comprehension is much faster:

In [1]: import copy
In [2]: iv = [range(100) for _ in range(10)]

In [3]: %timeit copy.deepcopy(iv)
47.8 µs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [4]: %timeit [lst[:] for lst in iv]
2.63 µs ± 33.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

你试过self.current_value = self.initial_value吗?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM