patternpythonMinor
Changing a character in a string at a specified index position
Viewed 0 times
indexcharacterpositionchangingstringspecified
Problem
Could you please tell me what you liked or may have disliked about this code? What can be made better?
```
#!/usr/bin/python3
def change_char_at(ch, s, indx):
"""
Strings in Python are immutable objects. So, it is not possible to change a
certain character in a string in place. For example, an attempt to run the
following code will fail with a TypeError:
s = "spam"
s[1] = "z" # TypeError: 'str' object does not support item assignment
What this function does is it provides you with a nice interface when you
want to change a character in a string at a certain index position. So, use
this function instead of doing everything manually which can sometimes be
tricky. Notice that the character parameter does not necessarily have to be
one character long. It can be an empty string which means that a character
at a certain position will effectively be deleted from the string. If it's
more than one character long, then they all will be inserted into the string
starting at the specified index position.
Parameters:
ch: character to insert
s: string to insert into
indx: index position where to insert the character
"""
# Error handling
if type(ch) is not str:
raise TypeError("first argument must be a string")
if type(s) is not str or not len(s) > 0:
raise TypeError("second argument must be a non-empty string")
length = len(s) - 1
if not(indx >= 0 and indx <= length):
msg = "string index out of range; "
msg += "attempt to access index at {0}; ".format(indx)
msg += "allowable index range 0 to {0}".format(length)
raise IndexError(msg)
# Actual function logic
return s[:indx] + ch + s[indx + 1:]
"""
Another possible implementation:
ls = list(s)
ls[indx] = ch
return ''.join(ls)
This works well too and is equally good, but might be conspired unpythonic
by some compared
```
#!/usr/bin/python3
def change_char_at(ch, s, indx):
"""
Strings in Python are immutable objects. So, it is not possible to change a
certain character in a string in place. For example, an attempt to run the
following code will fail with a TypeError:
s = "spam"
s[1] = "z" # TypeError: 'str' object does not support item assignment
What this function does is it provides you with a nice interface when you
want to change a character in a string at a certain index position. So, use
this function instead of doing everything manually which can sometimes be
tricky. Notice that the character parameter does not necessarily have to be
one character long. It can be an empty string which means that a character
at a certain position will effectively be deleted from the string. If it's
more than one character long, then they all will be inserted into the string
starting at the specified index position.
Parameters:
ch: character to insert
s: string to insert into
indx: index position where to insert the character
"""
# Error handling
if type(ch) is not str:
raise TypeError("first argument must be a string")
if type(s) is not str or not len(s) > 0:
raise TypeError("second argument must be a non-empty string")
length = len(s) - 1
if not(indx >= 0 and indx <= length):
msg = "string index out of range; "
msg += "attempt to access index at {0}; ".format(indx)
msg += "allowable index range 0 to {0}".format(length)
raise IndexError(msg)
# Actual function logic
return s[:indx] + ch + s[indx + 1:]
"""
Another possible implementation:
ls = list(s)
ls[indx] = ch
return ''.join(ls)
This works well too and is equally good, but might be conspired unpythonic
by some compared
Solution
The fact that your function is named
I'm not a fan of this function, though. Basically, it's a long-winded way to do
In summary, if you want to do s[:indx] + ch + s[indx + 1:]
change_char_at and the first parameter is named ch both suggest that ch should be a single character. However, the function could easily be abused to splice in any number of characters at that location, including zero. So, you might as well make it obvious and rename the function to string_splice() or something.I'm not a fan of this function, though. Basically, it's a long-winded way to do
s[:indx] + ch + s[indx + 1:] with some validation.if type(ch) is not strseems pointless. Ifchis not a string, it would naturally fail with aTypeErroranyway during concatenation.
if type(s) is not strmight be useful validation, but it also goes against Python's duck-typing philosophy.
if … not len(s) > 0is an unjustified special case. If you're going to allow splicing in an arbitrary number of characters, then why shouldn't one be allowed to add something to an empty string? As a consequence of this failure case, the caller will also need to put in a special case to work around this restriction.
if not(indx >= 0 and indx
In summary, if you want to do s[:indx] + ch + s[indx + 1:]
, then it's probably best to just write that. If you want to write this function anyway, I recommend dropping most, if not all, of the validation.
If you want to do a lot of single-character replacements, then you would probably want to convert the string to a list or bytestring` instead.Context
StackExchange Code Review Q#120417, answer score: 3
Revisions (0)
No revisions yet.