Reputation: 1203
I'm trying to understand the replace
method. I have a string of numbers where I would like to make some adjustments. Particularly, I would categorize the numbers based on a threshold:
def makeAdjustment(x):
for each in x:
if int(each) < 5:
x = x.replace(each, "0")
else:
x = x.replace(each, "1")
return x
In use:
>>> makeAdjustment("800857237867") == "100111001111"
True
>>> makeAdjustment("15889923") == "01111100"
True
>>> makeAdjustment("14963896") == "00110111"
True
However, if the sequence of numbers gets larger the string is converted to zero:
>>> makeAdjustment("366058562030849490134388085")
'000000000000000000000000000'
Upvotes: 2
Views: 108
Reputation: 160377
The issue here isn't that the string is larger, it's that instances of '1'
or '0'
shouldn't be replaced. When you encounter a '1'
later on in the string (as in your last case) you'll replace all previous instances of '1'
with '0'
.
One solution is to special case them:
def makeAdjustment(x):
for each in x:
if int(each) in {'1', '0'}:
continue
if int(each) < 5:
x = x.replace(each, "0", 1)
else:
x = x.replace(each, "1")
return x
This is one option but it isn't the best since you're calling replace
for every iteration. You can do much better by just using join
here:
def makeAdjustment(x):
return "".join("1" if int(i) > 5 else "0" for i in x)
which is cleaner, clearer and faster:
# for loop
%timeit makeAdjustment("366058562030849490343880185")
10000 loops, best of 3: 39.1 µs per loop
# join
%timeit makeAdjustment("366058562030849490343880185")
100000 loops, best of 3: 17.7 µs per loop
Upvotes: 3
Reputation: 33476
def makeAdjustment(x):
splitted = [c for c in enumerate(x)]
for each in splitted:
if int(each[1]) < 5:
splitted[each[0]] = "0"
else:
splitted[each[0]] = "1"
return "".join(splitted)
EDIT: The above code splits the string and makes a list of tuple where each character in the string is accompanied by index of it. This is done using enumerate
.
The list (splitted
) is enumerated where each[1]
will contain the actual character from the string whereas each[0]
will contain the index of the actual character in the given string.
Based on the value contained in each[1]
the value contained at each[0]
index of the splitted is modified.
In the end, the string is joined using "".join(splitted)
.
Upvotes: 1
Reputation: 4477
My way of doing it is just to turn it into a list and go by position. It's so much easier since replace is replacing All each characters no matter where the position Here we use each as an index to keep track of our location in the list
def makeAdjustment(x):
x = list(x)
for each in range(len(x)+1):
if int(x[each]) < 5:
x[each] = '0'
else:
x[each] = '1'
#Turn it back into a string instead of a list
x = "".join(x)
return x
Upvotes: 1
Reputation: 42748
If you want to replace each character, build a new string character by character instead of using replace
:
def makeAdjustment(x):
result = []
for each in x:
if int(each) < 5:
result.append("0")
else:
result.append("1")
return ''.join(result)
or in short:
def makeAdjustment(x):
return ''.join("0" if int(each) < 5 else "1" for each in x)
Upvotes: 2