'Creating multiple lists depending on previous lists item (cyclic definition)

I need to generate multiple lists but element i for the first list depends on elements i-1 of the last list, as shown in the code below:

# a, b, c are lists of the same size
# foo() and bar() are just functions that returns a float

a = [...]
b = [...]
c = [...] 

# definition of lists
a[i] = a[i-1] + c[i-1]
b[i] = foo(a[i])
c[i] = bar(b[i])

My implementation so far:


a = []
b = []
c = []

for i in range(300):
    # a_0 is the initial value for a[0]
    a.append(a_0 if i == 0 else a[i-1] + c[i-1])
    b.append(foo(a[i]))
    c.append(bar(b[i]))

I feel there is a more elegant way to do this. Also in my case I have 18 lists, so the code is not the most readable.
Do you have any suggestions?



Solution 1:[1]

Two things:

  1. You can't iterate over range(len(a)), because a is empty at the moment. You need to iterate over some sequence representing the final length of a/b/c.

  2. You don't really care about arbitrary elements of the three lists, only the last element of each.

As such, you can initialize a_0 to some value, then simply append values to each list. a_0 can then be updated to reflect the value to be added to a on the next iteration.

a_0 = ...
for _ in range(10):
    a.append(a_0)
    b.append(foo(a[-1]))
    c.append(bar(b[-1]))
    a_0 = a[-1] + c[-1]

 

Solution 2:[2]

Remember that x[-1] always gives you the last element of x. So, just pre-fill your first elements and you have a simple loop:

a = [a_0]
b = [0]
c = [0]

for _ in range(300):
    a.append( a[-1] + c[-1] )
    b.append( foo(a[-1]) )
    c.append( bar(b[-1]) )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chepner
Solution 2