String handling in Python

Viewed 70

I am trying to write a short python function to break a long one_line string into a multi_line string by inserting \n. the code works fine when i simply insert \n into the string but i get an index out of range error when i insert a conditional check to add hyphenation as well. Here is the code that i have written.

Sentence = "Python string comparison is performed using the characters in both strings. The characters in both strings are compared one by one. When different characters are found then their Unicode value is compared. The character with lower Unicode value is considered to be smaller."
for i in range(1, int(len(Sentence)/40)+1):
    x = i*40
    Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]
print(Sentence)

Here is the error message i get.

Traceback (most recent call last):
  File "/media/u1/data/prop.py", line 4, in <module>
    Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]
IndexError: string index out of range
3 Answers

The conditional expression is greedy, parsed as if you had written

Sentence = Sentence[:x] + \
           ("\n" if Sentence[x] == " " else "-\n" + Sentence[x:])

As a result, you are doing one of two operations:

  1. Sentence[:x] + '\n' if you find a space
  2. Sentence[:x] + "-\n" + Sentence[x:] if you find a different character.

Note that case 1 shortens your sentence incorrectly, but your range object is based on the original correct list.

The solution is to use parentheses to define the conditional expression correctly:

for i in range(1, int(len(Sentence)/40)+1):
    x = i*40
    c = Sentence[x]
    Sentence = Sentence[:x] + (f"\n" if c == " " else f"{c}-\n") + Sentence[x+1:]
    #                         ^                                ^

Well the issue might not be obvious in the start but when you start looking at the if statement in the middle of string concatenation, you will understand. For a minute just focus on the following line:

Sentence = Sentence[:x] + "\n" if Sentence[x] == " " else "-\n" + Sentence[x:]

Python would parse this statement like so:

Sentence = (Sentence[:x] + "\n") if Sentence[x] == " " else ("-\n" + Sentence[x:])

Notice the brackets carefully. This is exactly the reason why the length of the string held by the variable Sentence is decreasing after each iteration which triggers the IndexError exception. Hence, in order to address this issue, we will have to explicitly tell Python what we are expecting. So, it could be written as such:

Sentence = Sentence[:x] + ("\n" if Sentence[x] == " " else "-\n") + Sentence[x:]
string = "Python string comparison is performed using the characters in both strings. The characters in both strings are compared one by one. When different characters are found then their Unicode value is compared. The character with lower Unicode value is considered to be smaller."
stc = ""

for j in range(1 + len(string) // 40):
    stc += string[j * 40:40 * (j + 1)] + "\n"

print(stc)
Related