Why does Python remove leading zeroes when converting from string to int? - python

>>> num = int('0241034812')
>>> print(num)
241034812
>>>
In the above code, I'm setting the variable num to 0241034812; however, when I print the variable it deletes the first zero.
Why is this happening?

Integers are stored/displayed as a "normal" number, not the string value. If you want to display the number prefixed with zeroes you can do that when displaying the variable.
You can use the following syntax to add leading zeros to an integer:
print "%010d" % (241034812,)
The example above will display the integer 241034812 with 10 digits as 0241034812.

I'm setting the variable 'num' to '0241034812'
No, you're setting it to 241,034,812: an integer value, about two hundred forty million. If you want to set it to '0241034812', you should use a string rather than an integer. That is, you should drop the call to int:
>>> num = '0241034812'
>>> print(num)
0241034812
>>>

If you're storing some number in a format where a leading zero would be useful/significant (maybe a barcode, ISBN, or the like), you can re-add them when converting back into a string using .format
>>> num = int('0241034812')
>>> print('{:010d}'.format(num))
0241034812
Briefly, the first 0 in the format spec means to add leading zeros if not present to fill 10 (the 10) characters.

You wanted to print your integer to a specific zero-padded width, use string formatting. The format() function, for example:
>>> num = 241034812
>>> print(format(num, '010d'))
0241034812
or print the original string from which you parsed the integer in the first place.
Integers do not store a 'print width' or any number of leading 0 digits.

Related

Keep zero digit save while converting string to integer in python

I am converting a string into integer using int function and it is working fine but i want to keep save zero digit that are at the start of the string.
string_value = '0123'
print(int(string_value))
result is 123
How can i format output 0123 as in integer type value not in string.
You can't, but if you want to put 0's (zero padding) at the beginning of your number, this is the way to do it.
"{:04}".format(123)
# '0123'
"{:05}".format(123)
# '00123'
Like every one said you can try above answers or the following :
string_value = '0123'
int_no = int(string_value)
print("%04d" % int_no)
print(string_value.zfill(4))
Both will give same answer
Impossible, you cannot get an integer value of 0123.
You should change your mind, you do not actually need 0123 in integer, but you need to keep zero when displaying it. So the question should change to how to format output.

How to convert octal to string without change the value?

How to convert 00024 to '00024' with python?
If I run 00024 in python shell, it print 20 as result. I want to convert 00024 to string, with the result is '00024'. Any suggestions?
If you want to represent integers with leading zeros, format() the number to a string explicitly:
format(integer, '05d')
Whenever you output values, print implicitly converts it to a string with str(), with format() you get to control how that conversion takes place explicitly.
When you echo a number in the interactive interpreter, repr() is used instead, but for integers the output is exactly the same as when you use str().
Demo:
>>> format(24, '05d')
'00024'
When you enter 00024 as an integer literal, Python 2 parses that as an octal number, in Python 3 that's a syntax error.
If you want to interpret such a number in the Python 2 shell as if it was a string, you cannot do what you want, not with an arbitrary number of leading zeros. You can, at best, re-format the resulting integer as octal, again with leading zeros. That'll produce a string again, but you have to hardcode the number of leading zeros:
>>> number = 00024
>>> format(number, '05o')
'00024'
Note that this'll also fail as soon as you have a number that doesn't have a leading zero; you could auto-detect such values if they are greater than 4095 (07777 octal):
strnumber = format(number, '5d' if number > 0o07777 else '05o')
and any number with leading zero and the digits 8 or 9 simply fails with a syntax error:
>>> 09876
File "<stdin>", line 1
09876
^
SyntaxError: invalid token
Your better bet is to just enter such numbers as strings instead.

Convert a list of float to string in Python

I have a list of floats in Python and when I convert it into a string, I get the following
[1883.95, 1878.3299999999999, 1869.4300000000001, 1863.4000000000001]
These floats have 2 digits after the decimal point when I created them (I believe so),
Then I used
str(mylist)
How do I get a string with 2 digits after the decimal point?
======================
Let me be more specific, I want the end result to be a string and I want to keep the separators:
"[1883.95, 1878.33, 1869.43, 1863.40]"
I need to do some string operations afterwards. For example +="!\t!".
Inspired by #senshin the following code works for example, but I think there is a better way
msg = "["
for x in mylist:
msg += '{:.2f}'.format(x)+','
msg = msg[0:len(msg)-1]
msg+="]"
print msg
Use string formatting to get the desired number of decimal places.
>>> nums = [1883.95, 1878.3299999999999, 1869.4300000000001, 1863.4000000000001]
>>> ['{:.2f}'.format(x) for x in nums]
['1883.95', '1878.33', '1869.43', '1863.40']
The format string {:.2f} means "print a fixed-point number (f) with two places after the decimal point (.2)". str.format will automatically round the number correctly (assuming you entered the numbers with two decimal places in the first place, in which case the floating-point error won't be enough to mess with the rounding).
If you want to keep full precision, the syntactically simplest/clearest way seems to be
mylist = list(map(str, mylist))
map(lambda n: '%.2f'%n, [1883.95, 1878.3299999999999, 1869.4300000000001, 1863.4000000000001])
map() invokes the callable passed in the first argument for each element in the list/iterable passed as the second argument.
Get rid of the ' marks:
>>> nums = [1883.95, 1878.3299999999999, 1869.4300000000001, 1863.4000000000001]
>>> '[{:s}]'.format(', '.join(['{:.2f}'.format(x) for x in nums]))
'[1883.95, 1878.33, 1869.43, 1863.40]'
['{:.2f}'.format(x) for x in nums] makes a list of strings, as in the accepted answer.
', '.join([list]) returns one string with ', ' inserted between the list elements.
'[{:s}]'.format(joined_string) adds the brackets.
str([round(i, 2) for i in mylist])
Using numpy you may do:
np.array2string(np.asarray(mylist), precision=2, separator=', ')

Strings, ints and leading zeros

I need to record SerialNumber(s) on an object. We enter many objects. Most serial numbers are strings - the numbers aren't used numerically, just as unique identifiers - but they are often sequential. Further, leading zeros are important due to unique id status of serial number.
When doing data entry, it's nice to just enter the first "sequential" serial number (eg 000123) and then the number of items (eg 5) to get the desired output - that way we can enter data in bulk see below:
Obj1.serial = 000123
Obj2.serial = 000124
Obj3.serial = 000125
Obj4.serial = 000126
Obj5.serial = 000127
The problem is that when you take the first number-as-string, turn to integer and increment, you loose the leading zeros.
Not all serials are sequential - not all are even numbers (eg FDM-434\RRTASDVI908)
But those that are, I would like to automate entry.
In python, what is the most elegant way to check for leading zeros (*and, I guess, edge cases like 0009999) in a string before iterating, and then re-application of those zeros after increment?
I have a solution to this problem but it isn't elegant. In fact, it's the most boring and blunt alg possible.
Is there an elegant solution to this problem?
EDIT
To clarify the question, I want the serial to have the same number of digits after the increment.
So, in most cases, this will mean reapplying the same number of leading zeros. BUT in some edge cases the number of leading zeros will be decremented. eg: 009 -> 010; 0099 -> 0100
Try str.zfill():
>>> s = "000123"
>>> i = int(s)
>>> i
123
>>> n = 6
>>> str(i).zfill(n)
'000123'
I develop my comment here, Obj1.serial being a string:
Obj1.serial = "000123"
('%0'+str(len(Obj1.serial))+'d') % (1+int(Obj1.serial))
It's like #owen-s answer '%06d' % n: print the number and pad with leading 0.
Regarding '%d' % n, it's just one way of printing. From PEP3101:
In Python 3.0, the % operator is supplemented by a more powerful
string formatting method, format(). Support for the str.format()
method has been backported to Python 2.6.
So you may want to use format instead… Anyway, you have an integer at the right of the % sign, and it will replace the %d inside the left string.
'%06d' means print a minimum of 6 (6) digits (d) long, fill with 0 (0) if necessary.
As Obj1.serial is a string, you have to convert it to an integer before the increment: 1+int(Obj1.serial). And because the right side takes an integer, we can leave it like that.
Now, for the left part, as we can't hard code 6, we have to take the length of Obj1.serial. But this is an integer, so we have to convert it back to a string, and concatenate to the rest of the expression %0 6 d : '%0'+str(len(Obj1.serial))+'d'. Thus
('%0'+str(len(Obj1.serial))+'d') % (1+int(Obj1.serial))
Now, with format (format-specification):
'{0:06}'.format(n)
is replaced in the same way by
('{0:0'+str(len(Obj1.serial))+'}').format(1+int(Obj1.serial))
You could check the length of the string ahead of time, then use rjust to pad to the same length afterwards:
>>> s = "000123"
>>> len_s = len(s)
>>> i = int(s)
>>> i
123
>>> str(i).rjust(len_s, "0")
'000123'
You can check a serial number for all digits using:
if serial.isdigit():

Why do I have to convert numbers into strings to get its location?

Why will it not print out the position of a integer/float until I have converted it to a string?
example
x = 123
print x[0] # error
To fix this I have to do
x = 123
print str(x)[0]
But why do I have to make it into a string for it to work?
Well, why should this work in the first place? What is the nth index of a number; what is index 0 of the decimal number 123?
Is it 1 because of its decimal representation?
Is it 7 because of its hexadecimal representation (7B)?
Is it 0 because of its hexadecimal representation (0x7B)?
Is it 1 because of its octal representation (173)?
Is it 0 because of its octal representation (0173)?
Is it 1 because of its binary representation (1111011)
Is it 1 because of its binary representation with the least significant bit first (1101111)?
Is it S because that’s what 123 is in ASCII?
…
As you can see, this is very unclear, and it does not make sense to begin with. When using the index access on a list, you get the nth element of the list. When you use the index access on a sequence, you get the nth element of the sequence. A string is a sequence of characters, so when using the index access on a string, you get the nth element of the string sequence; the nth character. A number is no sequence, only its string representation in some format is.
123 is but one representation of the integer value. Python int values are not sequences or mappings, so [item] indexing has no meaning for them.
By turning the number into a string, you 'capture' the representation into a series of digit characters and you then can get the first one.
Another way to do it would be to divide by 10 until you have a number lower than 10:
x = 123
while x > 10:
x //= 10
print x # prints the number 1
Note that x then holds an int still, not a single-character string.
The simple answer is because you have the wrong type. Integers don't support indexing -- and I really don't think they should (they're not sequences or mappings and I can't think of any way that indexing an integer actually makes sense).
Note that there is more than one way to represent an integer as well:
>>> 0x7b == 123
True
So in this case, who is to say that x[0] should return 1 instead of 0 (or 7) depending on how you want to think of it?
As a side note to the excellent answers above, this is one way you can convert a number to a list of numbers to allow indexing:
In [2]: map(int,str(123))
Out[2]: [1, 2, 3]
In [3]: map(int,str(123))[0]
Out[3]: 1
In [4]: type(map(int,str(123))[0])
Out[4]: int

Categories

Resources