Can I keep a list of references, that auto update in the list?

Question:

In its essence, I do this:

a = True
b = False
ls = [a, b]

a = False

print(ls)
> [True, False]

And what happens is that whatever happens to a is decoupled from the list after the first inclusion. Is there any way to update a and also have the list updating itself, in a clean way?

Of course I could simply do ls[0] = False and be done. But in a large project, with many moving parts, I’d like to avoid non-descriptive bracket indexing.

I assume I could do some messy construct of an instantiated class, and then iterate over the attributes, but that sounds like messy business. Or is it?

Asked By: komodovaran_

||

Answers:

If you want to avoid indexing and have easy to read attributes then you could just use a class that has class attributes:

class Data:
    a = True

and keep multiple references to it:

data = Data
data2 = Data  # or similarly data2 = data

data.a = False
print(data2.a)
# False

Note that if you instantiate the class you’ll need to keep a reference to the instance rather than the class as the original class won’t be updated anymore:

data = Data()
data2 = data

data.a = 123
print(data2.a)
# 123

# original class remains unchanged
print(Data().a)
# True

From Python 3.7 you can use a dataclass, which makes instantiation with custom data simpler:

from dataclasses import dataclass

@dataclass
class Data:
    a = True

data = Data(a=False)
data2 = data
print(data2.a)
# False

Finally, if you do care about variable states then there’s a good chance you’ll be working within a class anyway, in which case you could use a property:

class SomeClass:
    def __init__(self):
        self.a = False
        self.b = True

    @property
    def ls(self):
        return self.a, self.b
    
some_class = SomeClass()
some_class.a = True
print(some_class.ls)
# True, True
Answered By: 101

I suggest you this quite simple solution defining ls as a function instead of a simple list. In this way, ls() will always returns the updated values of aand b. The code is very close to your original code:

a = True
b = False

ls = lambda:[a,b]

a = False
print(ls())  # [False, False]

b = True
print(ls())  # [False, True]
Answered By: Laurent H.
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.