It's because .index() returns the lowest or first index of the substring within the string. Since the first occurrence of l in hello is at index 2, you'll always get 2 for "hello".index("l").
So when you're iterating through the characters of hello, you get 2 twice and never 3 (for the second l). Expanded into separate lines, it looks like this:
"hello".index("h") # = 0
"hello".index("e") # = 1
"hello".index("l") # = 2
"hello".index("l") # = 2
"hello".index("o") # = 4
Edit: Alternative way to get all indices:
One way to print all the indices (although not sure how useful this is since it just prints consecutive numbers) is to remove the character you just read from the string:
removed = 0
string = "hello world" # original string
for char in string:
print("{} at index {}".format(char, string.index(char) + removed)) # index is index() + how many chars we've removed
string = string[1:] # remove the char we just read
removed +=1 # increment removed count
indexalways returns the index of the first occurrenceenumerate()function to get all index of each and every char in the string. eg.for idx, ch in enumerate(text):