Home > Mobile >  Why does it insert it more than once?
Why does it insert it more than once?

Time:07-11

Trying to insert " _ " before uppercase letters but it inserts more than once.

Instead of ["h", "e", "l", "l", "o", " _ ", "W", "o", "l", "r", "d"] it prints ['h', 'e', 'l', 'l', 'o', ' _ ', ' _ ', ' _ ', ' _ ', 'W', 'o', 'l', 'r', 'd']

new = ["h", "e", "l", "l", "o", "W", "o", "r", "l", "d"]

for i in range(len(new)):
    print(i)
    if new[i].isupper():
        new.insert(i, "_")

print(new)

CodePudding user response:

Because after you insert '_' at index i, the uppercase letter (W) is moved to the right and thus gets the index i 1. Now the for loop iteration completes, and i gets incremented and becomes i 1, but guess what is at index i 1? (Hint: W) So, this is a cycle that only exhausts when the for loop iterates len(new) times. Below is what the execution might look like:

  • (i=0): new[i] is 'h'
  • (i=1): new[i] is 'e'
  • (i=2): new[i] is 'l'
  • (i=3): new[i] is 'l'
  • (i=4): new[i] is 'o'
  • (i=5): new[i] is 'W' --> insert '_' --> 'W' moves to new[i 1]
  • (i=6): new[i] is 'W' --> insert '_' --> and this pattern repeats

A simple solution would be to run backwards. As now, insert '_' will push 'W' to the right, while we are moving to the left; therefore, we won't end up in the cycle like before.

new = ["h", "e", "l", "l", "o", "W", "o", "r", "l", "d"]
start = len(new) - 1 # last element
end = -1 # one prior to the first element
         # remember, range end is non-inclusive,
         # so it goes till index 0
step = -1 # decrement to move backwards
for i in range(start, end, step):
    if new[i].isupper():
        new.insert(i, "_")
print(new)

CodePudding user response:

You can create a new list:

new = ["h", "e", "l", "l", "o", "W", "o", "r", "l", "d"]

result = []
for i in range(len(new)):
    if new[i].isupper():
        result.append("_")
    result.append(new[i])

print(result)

CodePudding user response:

In your code, each call to new.insert(i, "_") changes new so that the uppercase letter that was previously at index i is now a index i 1, since you have just inserted the character _ at index i and pushed he uppercase letter (and every item that comes after it in the list new) one position higher.

One way to fix this would be to loop through new in reverse order using python's built-in function reversed():

new = ["h", "e", "l", "l", "o", "W", "o", "r", "l", "d"]

for i in reversed(range(len(new))):
    #print(i)
    if new[i].isupper():
        new.insert(i, "_")

print(new)

Now, after examining the character at index i, detecting that it's uppercase, and inserting _ at i, the next loop iteration examines the character at position i - 1, which was unaffected by the prior iteration's call to new.insert(i, "_"). Output:

['h', 'e', 'l', 'l', 'o', '_', 'W', 'o', 'r', 'l', 'd']
  • Related