Reputation: 3
a_string = 'abc'
destination = [2, 3]
edges = { (1, 'a') : [2, 3],
(2, 'a') : [2],
(3, 'b') : [4, 3],
(4, 'c') : [5] }
def make(a_string, destination, edges):
n = 0
while n + 1 < len(a_string):
letter = a_string[n]
letter2 = a_string[n + 1]
for d in destination: # (1)
if (d, letter2) in edges:
for state in edges[(d, letter2)]:
destionation.append(state)
destination.remove(d)
n += 1 # (2)
return destination
The code return []
, but I expect to see [5]
, so I think the problem is that it increment n
unexpectedly then make letter2
change.
Why does this code increment n
(at position 2) before completing the for
loop (at position 1)?
Upvotes: 0
Views: 125
Reputation: 1929
n will not be incremented before the loop is done. The thing you are probably missing is that the while loop checks for n+1 instead of n.
edit now we have more information:
The problem is that you are removing items from an iterator which has undefined behavior.
try
for d in destination[:]:
This is the slice operator on the entire array, so it acts as a copy constructor. You are now looping over a different object and the remove should be safe.
Upvotes: 1
Reputation: 174614
You can iterate over strings as well, and using the index
method of strings you can grab the next position of the character.
Combining those two, your initial outer loop can be simplified:
def make(a_string, destination, edges):
for letter in a_string:
while a_string.index(letter)+1 < len(a_string):
next_letter = a_string[a_string.index(letter)+1]
In addition, you shouldn't name your variable string
as it is the name of a module.
Upvotes: 0
Reputation: 9975
If you don't add 1 to n at the end of the loop, the loop condition stays the same and the loop will be executed forever. It's not executed in the for loop but in the while loop body. (Indentation determines to which block of code a line belongs!)
Upvotes: 0