3

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:

  1. 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:

  1. Easiest way to convert int to string in C++

  2. http://we.easyelectronics.ru/Soft/preobrazuem-v-stroku-chast-1-celye-chisla.html

Article that is trying to explain this process by dividing number number / 10 and number % 10:

  1. How are integers converted to strings under the hood?
sjakobi
3,6081 gold badge28 silver badges44 bronze badges
asked Apr 22, 2021 at 11:07
3
  • 1
    Did you check how these classes are instantiated? For example, int Commented Apr 22, 2021 at 11:38
  • Yes, but str says that if all is ok then returns object.__str__() . Here --> "and the built-in functions format() and print() to compute the "informal" or nicely printable string representation of an object. The return value must be a string object." Looks like a circle. Commented Apr 22, 2021 at 12:12
  • That makes sense, actually. The __str__ method of a class returns its string representation, which is what print() (as well as str()) will return when called on an instance of that class. Maybe having a go at OOP with Python and creating your first classes will help with this. Commented Apr 22, 2021 at 12:27

1 Answer 1

2

String to integer

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:

  1. our int method will only deal with int inputs, no floats, complex numbers, etc. for now.
  2. we will only deal with positive numbers for now as well.
  3. I won't be dealing with intentionally wrong inputs, like int("Wassup")

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.

Integer to string

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'>

answered Apr 22, 2021 at 11:57
Sign up to request clarification or add additional context in comments.

4 Comments

Is this a real way how str() or better to say magic method __str__() work? I mean it holds an i_to_s_dict-like dictionary of values as you mention above, adds some more processing functions and that's it? Anyway sounds good! What is about if I want to dig deeper... where I can find this source code? Or it's C++/CPython code and for now, I can't understand it? Thank You for a good explanation!
I've been trying to find where the int class defines str or vice versa digging through the cpython source code and I've had no luck, it gets really complex. I wasn't able to track the concrete implementation of int, but feel free to continue researching. The source is here: github.com/python/cpython/tree/…
@m.oulmakki See here: github.com/python/cpython/blob/…
In brief, Python converts the array of binary limbs in the integer to groups of decimal digits: typically, it's converting from base 2**30 to base 10**9.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.