Here we modify the string s
while looping on it:
s = 'hello'
for c in s:
s += c
print(s)
It doesn't generate an infinite loop (it could: we add a new character in each iteration!).
I know this since years, but I can't really explain why. Has this something to do with string immutability or is it not related?
When doing for c in s:
, is the original s
copied in memory before starting the loop?
Another case that I thought could generate an infinite loop, but it does not:
s = 'hello'
def f(x):
i = 0
while True:
try:
yield x[i]
except IndexError:
break
i += 1
for c in f(s):
s += c
print(s)
It doesn't generate an infinite loop (it could: we add a new character in each iteration!).
It is because strings in Python are immutable.
When you do for c in s
, for
loop iterates over original object (object containing "hello"
) and when you do s += c
, a new string is created and hence, you aren't modifying the original string object that for
loop is still iterating over.
Also, adding @Steven Rumbalski 's comment in my answer:
It iterates over the original object. Rebinding the name to a new object doesn't change the for-loop because it doesn't resolve the name on each iteration.
Now, Let's talk about second example of yours:
If you call your function f(s)
, it makes it's formal argument x
to point to the object containing the string "hello" and it creates a generator using the string object. Now, subsequent re-assignment of the string s
(using s += c
) actually creates another string and doesn't effect the original object. Your function's formal argument is still pointing to an object containing "hello"
.
So, after first iteration of your for loop in the second example:
Formal argument of function f(x)
will be still pointing to an object containing "hello".
s will be pointing to an object containing "helloh"
.
IMPORTANT:
However, if you try your code with mutable data types, it may create an infinite loop. See this:
li = [ 1, 2, 3, 4 ]
for i in li:
li.append(i)
print(li)
Mutate a list to accomplish what you want.
array = list('hello')
for c in array:
array.append(c)
print(*array, sep='')
prints
helloh
hellohe
hellohel
hellohell
hellohello
hellohelloh
hellohellohe
hellohellohel
hellohellohell
hellohellohello
hellohellohelloh
hellohellohellohe
...
If you want to loop by one character continuously you can do
from itertools import cycle
for c in cycle('hello'):
print(c)
prints
h
e
l
l
o
h
e
l
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With