alphanumeric
alphanumeric

Reputation: 19359

How to create dynamic link between list variables

The dictionary's methods .viewvalues() and .viewkeys() allow to create the list variables that will be linked and dynamically updated on every dictionary modification such as:

diction={'one':1,'two':2,'three':3}
dict_values=dictVar.viewvalues()
dict_keys=dictVar.viewkeys()

I wonder if a similar functionality could be achieved with lists. So if there are two "source" list variables and a third list is a result of sums of twos:

a=[1,2,3]
b=[4,5,6]
sum=a+b

Now what i want is a list variable sum to get updated if/when list variable a or list variable b is modified. How to achieve that?

Upvotes: 1

Views: 157

Answers (3)

Kevin London
Kevin London

Reputation: 4728

I'd define a function to do it and then call that whenever you need the list.

a=[1,2,3]
b=[4,5,6]

def sum(a, b):
    return a + b

Then, in an interpreter:

>>> sum(a, b)
[1, 2, 3, 4, 5, 6]
>>> a.append(5)
>>> sum(a, b)
[1, 2, 3, 5, 4, 5, 6]

If it's not necessary that it be a flat list, you can easily do what you'd want.

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> sum = [a, b]
>>> print(sum)
[[1, 2, 3], [4, 5, 6]]
>>> a.append(8)
>>> print(sum)
[[1, 2, 3, 8], [4, 5, 6]]

That said, I'd recommend against defining a variable named sum as it's a built-in Python function.

Upvotes: 1

Jon
Jon

Reputation: 332

You will have to right a custom data structure to do this. Here is something in the right direction...

class LinkedArrays(object):
    def __init__(self, sourceArray1, sourceArray2, combineFunction):
        self.sa1, self.sa2 = sourceArray1, sourceArray2

        self.__combineFunction = combineFunction
        self.__update()

    def updateSourceArray1(self, index, value):
        self.sa1[index] = value
        self.__update()

    def updateSourceArray2(self, index, value):
        self.sa2[index] = value
        self.__update()

    def __update(self):
        self.combinedArray = [self.__combineFunction(self.sa1[i], self.sa2[i]) for i in range(len(self.sa1))]

    def __getitem__(self, item):
        return self.combinedArray[item]


summedArrays = LinkedArrays([1, 2, 3], [4, 5, 6], lambda x, y: x+y)
print summedArrays[0]  # print 5

summedArrays.updateSourceArray1(0, 6)
print summedArrays[0]  # print 10

Upvotes: 0

tobias_k
tobias_k

Reputation: 82929

You could do it the other way around, using numpy arrays.

>>> import numpy as np
>>> ab = np.array([1,2,3,4,5,6])
>>> a = ab[:3]
>>> b = ab[3:]
>>> a, b
(array([1, 2, 3]), array([4, 5, 6]))
>>> a[1] = 9
>>> ab
array([1, 9, 3, 4, 5, 6])
>>> ab[0] = 7
>>> a
array([7, 9, 3])

Here, a and b are "views" on the array ab, and modifying one will also modify the other.

Starting with a and b, just create a numpy array from a+b and redefine a and b accordingly:

>>> a, b = [1,2,3], [4,5,6]
>>> ab = np.array(a+b)
>>> a, b = ab[:3], ab[3:]

Upvotes: 1

Related Questions