Reputation: 43
I'm new to Python and face a real problem in understanding the way how
str(123)
or int('123')
functions work.
I tried to check builtins.py but there's kinda a mess of functions and methods that I can't understand. Is it all about binary conversion?
As a wrong example:
str(123)
=> bin(123)
-> 1111011
-> 1100101 + 1111011 + 1010101
-> compare with some-table
-> '123'Are there any simple explanations or articles that can help?
How do str()
, int()
do their "conversion magic"? Would be perfect if you answer me in Python-like style but it's not nessescary...
Articles in C++ that are beyond my experience:
Article that is trying to explain this process by dividing number number / 10
and number % 10
:
Upvotes: 3
Views: 1258
Reputation: 306
Let's start with converting a string to an int, as I think it's a bit simpler to think through. I'll make a few assumptions to start:
The implementation will go through the string input from right to left, and build up the integer number by number.
def custom_int(input):
# Your intuition is right that we will need some kind of look up! this matches a character to a number
s_to_i_dict= {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
# imagine our input is the string "123", we want to build up the number 123
# one digit at a time. If you break it down, 123 is equal to 100 + 20 + 3
# Thinking it through further, that's the same as 1*100 + 2*10 + 3*1
# So for each digit going right to left, we'll multiply it by some multiplier
# add it to our result, theb change that multiplier to handle the next digit.
multiplier = 1
output = 0
# This is a little shortcut to get you looping through a list or a string from the last element to the first:
for digit in input[::-1]:
# digit is a character, we find the corresponding number, multiply it by the multiplier, then add it to the old version of output
output = output + ( s_to_i_dict[digit] * multiplier)
# we are done with this digit, so the next multiplier should be 10 times the last (going from digits to tens to hundreds etc.)
multiplier = multiplier * 10
return output
Running this you'd get:
s_to_i("123")
123
type(s_to_i("123"))
<class 'int'>
For the "123" input, our loop will run 3 times. the first time around output will just be the rightmost digit 3, the next time around, we will add 2*10 to output, giving us 23.
The final time through the loop we will get 23 + 1*100, or 123.
We can apply the exact same pattern to the int to string conversion. The same assumptions apply as I won't cover all edge cases, but fundamentally we will do the same thing: go through the numbers from right to left, then build up a string representation of the number.
Now we can't loop over numbers as easily as we loop over strings, but with some good use of mod and division we can get a similar pattern. say n = 123, how do we get just the rightmost digit from the number? Well the rightmost digit is the remainder of dividing n by 10, or in code rightmost_digit = n % 10.
Once we have the rightmost digit, the next step is to try to extract the second rightmost digit, 2 in this case. There are a few ways to do that but my favorite is to recognize that we have already grabbed the rightmost digit, so we don't need it anymore
We can update our number n as follows: n = n // 10
which will give n the value of 12 instead of 123. This is called integer division, and is basically primary school division before you discovered floats :P
How does this help? well notice that 2 is the rightmost digit of 12 and we already know how to grab that! Let's put this all together in a function.
def i_to_s(input):
# Notice that this is the opposite dictionary than before. ints are the key, and they give us the character we need.
i_to_s_dict={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9'}
# This time we want our output to be a string so we initialize an empty string
output = ""
# There are more precise ways to set up this loop, as this one creates an edge case I'll leave up to you to find, but works with _almost_ every integer :P
while(input != 0):
rightmost_digit = input % 10
# We concatenate the new character we found with the output we've accumulated so far
output = i_to_s(rightmost_digit) + output
# Change the initial number for the next iteration
input = input // 10
return output
i_to_s(123)
'123'
type(i_to_s(123))
<class 'str'>
Upvotes: 2