Reputation: 1026
for this list:
current_trace = [[3,5,1,5,7,9,4]]
I run the sliding_tristep()
method, which includes the predict()
and window()
methods:
def predict(lst):
print "predicting for", lst
print "result", max(lst) + 0.0
return max(lst) + 0.0
def window(lst, n=3):
for x in range(1, len(lst)+1): # or len(l)+n to continue till the end
yield(lst[max(0, x-n):x])
def sliding_tristep(full_trace, future_step = 2, window_size = 3):
for user_trace in full_trace:
for current_input in window(user_trace):
counter = 0
trace = current_input
accumulator = []
while counter <= future_step:
next_prediction = predict(trace)
trace.append(next_prediction)
accumulator.append(next_prediction)
trace = trace[-window_size:]
counter += 1
print current_input, accumulator
When I run sliding_tristep(current_trace)
, in the output for the print current_input, accumulator
line I notice that the current_input
has been modified although it is out of the while loop which makes the calculations in sliding_tristep(current_trace)
.
I wonder why does this happen? How is that possible for python to modify a list which is not used at all in the subsequent loop.
Upvotes: 2
Views: 86
Reputation: 24812
I run
sliding_tristep(current_trace)
, in the output for theprint current_input, accumulator
line I notice that thecurrent_trace
has been modified
just tested your code:
>>> current_trace = [[3,5,1,5,7,9,4]]
>>> sliding_tristep(current_trace)
...
>>> current_trace
[[3, 5, 1, 5, 7, 9, 4]]
current_trace
does not get modified.
I wonder why does this happen? How is that possible for python to modify a list which is not used at all in the subsequent loop.
Though, I guess you meant current_input
and not current_trace
.
current_input
gets modified, because trace
is a reference to current_input
and trace gets modified.
If you want to make a copy of current_input
as trace
, here's one way to do it:
>>> foo = [1,2,3]
>>> bar = foo[:]
>>> bar.append(4)
>>> foo
[1, 2, 3]
>>> bar
[1, 2, 3, 4]
applied to your code:
def sliding_tristep(full_trace, future_step = 2, window_size = 3):
for user_trace in full_trace:
for current_input in window(user_trace):
counter = 0
trace = current_input[:] # make a copy of current_input
accumulator = []
while counter <= future_step:
next_prediction = predict(trace)
trace.append(next_prediction)
accumulator.append(next_prediction)
trace = trace[-window_size:]
counter += 1
print current_input, accumulator
If you don't modify the elements of the list (and as integers are non-mutable, you can't), you can do the shallow copy as I'm suggesting you in the aforementioned example. If you're using mutable objects (lists
or other kind of objects), then you want to do a deep copy using the copy
module. Look at this answer: https://stackoverflow.com/a/184660/1290438 on this topic.
Upvotes: 2
Reputation: 1026
using trace.extend(current_input)
, instead of trace = current_input
solves the problem. although, a trace
list has to be initialized beforehand.
The solution would look like:
def sliding_tristep(full_trace, future_step = 2, window_size = 3):
for user_trace in full_trace:
for current_input in window(user_trace):
counter = 0
trace = [] #here is the solution
trace.extend(current_input) #here is the solution
accumulator = []
while counter <= future_step:
next_prediction = predict(trace)
trace.append(next_prediction)
accumulator.append(next_prediction)
trace = trace[-window_size:]
counter += 1
Upvotes: 0