Python does not convert long to int - python

I have a list by connection of two strings and then converting them to integer by:
for i in xrange(0, len(FromBus[1][0])):
FromBus[1][0][i] = int(str(FromBus[1][0][i]) + str(ToBus[1][0][i]))
List looks as following:
>>> FromBus[1][0][1:5]
[3724637724L, 3724837324L, 3724837707L, 3724837707L]
List is made of longs
>>> type(FromBus[1][0][1])
<type 'long'>
Due to post processing of data in different environment I am trying to convert the long type to integer type so I need to delete 'L' at the end of each variable.
However, all of the methods I have found, failed:
>>> int(FromBus[1][0][1])
3724637724L
>>> [int(i) for i in FromBus[1][0]][1:5]
[3724637724L, 3724837324L, 37248377071L, 37248377072L]
>>> map(int, FromBus[1][0][1:5])
[3724637724L, 3724837324L, 37248377071L, 37248377072L]
My question is, what is the source of the problem here? I can easily convert them to strings. But how can I still convert long to int, without doing it thorugh string method (convert long to strings deleting the last character at the end of each string and then converting it back again to integer).
Sufficient solution for me, would be also to manimulate csv writing function deleting 'L''s while writing.

The L is part of Python's representation of the value, to show you that it's a long(). The actual number is ... well, the actual number. So there isn't really a "suffix" to trim off.
int() will still return a long() if the value is too long to fit into an int() -- but you can use str() to get just the digits in a form which is convenient to put in a CSV file.
In fact, the Python csv module (unsurprisingly) already does something like this, so I am not altogether sure you need this for your stated scenario.

Basically any bit manipulation which has an implication of a value in the 32nd bit is said to be a long. 1 << 31 becomes a long. because the 1 there is positive and you moved it over. Likewise if you set the value above the 1^31 value it will become a long. If you perform an int operation on an out of range value it will stay a long. This is kinda annoying to old-school bit manipulators who know there's 32 bits to fiddle with shove these relevant 32 bits into that size of a register.
Python refuses to make your number negative if you just happen to fill the 32nd bit through any means that wasn't - or ~. So you need to peel off the 32nd bit force it negative with operations that won't trigger the long conversion.
def sign32neg(value):
if 0x80000000 <= value <= 0xFFFFFFFF:
value &= 0x7FFFFFFF
value = int(value)
value = ~value
value ^= 0x7FFFFFFF
return value
This will make longs that could be expressed as a 32 bit negative integer, be expressed as such.

Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> x = int
>>> x
<type 'int'>
>>> x = long
>>> x
<type 'long'>
>>> print x
<type 'long'>
>>>
So :
import struct
my_val, = struct.unpack('>d', my_string_part_if shorter_than_4Bytes_fill_\x00))
Another way :
>>> import binascii
>>> print int(binascii.hexlify("test"),16)
1952805748
>>>
**#be carefull always length 4 bytes**

Related

Using variables as slice indices for python

For a class I am learning how to slice integers. In the code below the variable halflength is equal to half of the length of the variable message.
new = message[halflength::]
halflength is equal to an integer, however whenever I run this code I get this error:
TypeError: slice indices must be integers or None or have an __index__ method
Basically I need to try and create a new string that is equal to the second half of the original string.
Example: original string 1234 would produce 34 as the new string.
I think the problem is you get a float type for halfLength after division, try to cast it to int, or use integer division
halfLength = int(halfLength)
or
halfLength = len(message) // 2
to do what you want to do try something like this:
halfLength=len(message)//2
newMessage=message[halfLength::]
if you get the length this way it will always be an integer that you can then use to get parts of stings with.
Make sure halflength is of type Integer.
You can use "isinstance" method to verify.
# python
Python 2.7.5 (default, Aug 2 2016, 04:20:16
>>> halflength = "4"
>>> isinstance(halflength,int)`
False`
>>> halflength=4
>>> isinstance(halflength,int)
True
>>>
Try This:
message[int(halflength)::]

ValueError when converting string received from Micro:bit radio into integer in Python [duplicate]

I have a string in the format: 'nn.nnnnn' in Python, and I'd like to convert it to an integer.
Direct conversion fails:
>>> s = '23.45678'
>>> i = int(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '23.45678'
I can convert it to a decimal by using:
>>> from decimal import *
>>> d = Decimal(s)
>>> print d
23.45678
I could also split on '.', then subtract the decimal from zero, then add that to the whole number ... yuck.
But I'd prefer to have it as an int, without unnecessary type conversions or maneuvering.
How about this?
>>> s = '23.45678'
>>> int(float(s))
23
Or...
>>> int(Decimal(s))
23
Or...
>>> int(s.split('.')[0])
23
I doubt it's going to get much simpler than that, I'm afraid. Just accept it and move on.
What sort of rounding behavior do you want? Do you 2.67 to turn into 3, or 2. If you want to use rounding, try this:
s = '234.67'
i = int(round(float(s)))
Otherwise, just do:
s = '234.67'
i = int(float(s))
>>> s = '23.45678'
>>> int(float(s))
23
>>> int(round(float(s)))
23
>>> s = '23.54678'
>>> int(float(s))
23
>>> int(round(float(s)))
24
You don't specify if you want rounding or not...
You could use:
s = '23.245678'
i = int(float(s))
"Convert" only makes sense when you change from one data type to another without loss of fidelity. The number represented by the string is a float and will lose precision upon being forced into an int.
You want to round instead, probably (I hope that the numbers don't represent currency because then rounding gets a whole lot more complicated).
round(float('23.45678'))
The expression int(float(s)) mentioned by others is the best if you want to truncate the value. If you want rounding, using int(round(float(s)) if the round algorithm matches what you want (see the round documentation), otherwise you should use Decimal and one if its rounding algorithms.
round(float("123.789"))
will give you an integer value, but a float type. With Python's duck typing, however, the actual type is usually not very relevant. This will also round the value, which you might not want. Replace 'round' with 'int' and you'll have it just truncated and an actual int. Like this:
int(float("123.789"))
But, again, actual 'type' is usually not that important.
I believe this is a useless bug that should be corrected in Python.
int('2') --> 2 That converts the string '2' into an the integer 2.
int(2.7) --> 2 Converts a float to an int.
int('2.7') SHOULD convert to 2. This is how Perl works, for example. Yes, this does two things at once. It converts the string and when it finds it is in a representation that is a float, it should convert to int.
Otherwise, why insist that float('2') should work? It is an integer string, because there is no decimal point. So it has to convert from string which is an integer, directly to float.
I don't know but perhaps someone can answer whether the python interpreter, if the required int(float(x)) is used, if it actually goes through the process of first converting to float and then converting to int. That would make this bug even more critical to correct.

Long type in Python-3, NameError: name 'long' is not defined

I am new to python.And one of my requirement is to deal with long values.The problem is i didnt know how to assign a long value.This question might be very silly.But im just now starting to learn the language.I have seen a blog and i tried something like this :
# Long program in Python
x=1
y = long(x)
print(type(y))
But i am getting an error like this:
Traceback (most recent call last):
File "main.py", line 4, in <module>
y = long(x)
NameError: name 'long' is not defined
Can anyone please help me in acheiving this?
The long() function is no longer supported by Python 3 (no pun intended). It only has one built-in integral type, named int; but it behaves mostly like the old long type. So you just need to use int() built-in function in python-3.x.
Also for more information here are the complete list of changes on integer type in python-3.x:
PEP 0237: Essentially, long renamed to int. That is, there is only one built-in integral type, named int; but it behaves mostly like the old long type.
PEP 0238: An expression like 1/2 returns a float. Use 1//2 to get the truncating behavior. (The latter syntax has existed for years, at least since Python 2.2.)
The sys.maxint constant was removed, since there is no longer a limit to the value of integers. However, sys.maxsize can be used as an integer larger than any practical list or string index. It conforms to the implementation’s “natural” integer size and is typically the same as sys.maxint in previous releases on the same platform (assuming the same build options).
The repr() of a long integer doesn’t include the trailing L anymore, so code that unconditionally strips that character will chop off the last digit instead. (Use str() instead.)
Octal literals are no longer of the form 0720; use 0o720 instead.
Forget about long vs. int or about lL suffixes. Python 2.7 will promote int to long if necessary. And all integers are "long" in Python 3 (the type is renamed to int).
Assume that integers have infinite precision in Python.
To assign and print large integer in Python, just assign and print it:
x = 2**100
print(x) # -> 1267650600228229401496703205376
It works on both Python 2 and 3. The result is the same.
Python 2.7.13 it works.
x=1
y = long(x)
type(y)
<type 'long'>
you no need to define a variable as 'long' in python. Python will take care of it by default
Eg :
>>> x = 1243254675876586798
>>> type(x)
<type 'long'>
Quote from diveintopython3:
Python 2 had separate types for int and long. The int datatype was
limited by sys.maxint, which varied by platform but was usually 2^32-1.
Python 3 has just one integer type, which behaves mostly like the old
long type from Python 2. See pep 237 for details.
Python interpreter allocates memory based on the data type of variable. Therefore, by assigning different data types to variables, you can store integers, strings and longs.
>>> a = "Hello"
>>> b = 123
>>> c = 123.0
>>> d = "a"
>>> type(a)
<type 'str'>
>>> type(c)
<type 'float'>
For specific to long type, you can append "l" or "L" in the value, caps "L" is recommended. Python
displays long integers with an uppercase L
>>> e = 1234L
>>> type(e)
<type 'long'>
>>> f=1234567891223341221
>>> f
1234567891223341221L
For variable "f", while displaying the value interpreter has appended "L" with value.
As mentioned by Kasra, in Python 2.x you can typecast variable type with long(), but this is no longer supported in Python 3. This is not required as Python interpreter usually takes care if value changes, until unless you want to do it explicitly
>>> b = 1234
>>> type(b)
<type 'int'>
>>> long(b)
1234L

How does Python manage int and long?

Does anybody know how Python manage internally int and long types?
Does it choose the right type dynamically?
What is the limit for an int?
I am using Python 2.6, Is is different with previous versions?
How should I understand the code below?
>>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>
Update:
>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>
int and long were "unified" a few versions back. Before that it was possible to overflow an int through math ops.
3.x has further advanced this by eliminating long altogether and only having int.
Python 2: sys.maxint contains the maximum value a Python int can hold.
On a 64-bit Python 2.7, the size is 24 bytes. Check with sys.getsizeof().
Python 3: sys.maxsize contains the maximum size in bytes a Python int can be.
This will be gigabytes in 32 bits, and exabytes in 64 bits.
Such a large int would have a value similar to 8 to the power of sys.maxsize.
This PEP should help.
Bottom line is that you really shouldn't have to worry about it in python versions > 2.4
Python 2 will automatically set the type based on the size of the value. A guide of max values can be found below.
The Max value of the default Int in Python 2 is 65535, anything above that will be a long
For example:
>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>
In Python 3 the long datatype has been removed and all integer values are handled by the Int class. The default size of Int will depend on your CPU architecture.
For example:
32 bit systems the default datatype for integers will be 'Int32'
64 bit systems the default datatype for integers will be 'Int64'
The min/max values of each type can be found below:
Int8: [-128,127]
Int16: [-32768,32767]
Int32: [-2147483648,2147483647]
Int64: [-9223372036854775808,9223372036854775807]
Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
UInt8: [0,255]
UInt16: [0,65535]
UInt32: [0,4294967295]
UInt64: [0,18446744073709551615]
UInt128: [0,340282366920938463463374607431768211455]
If the size of your Int exceeds the limits mentioned above, python will automatically change it's type and allocate more memory to handle this increase in min/max values. Where in Python 2, it would convert into 'long', it now just converts into the next size of Int.
Example: If you are using a 32 bit operating system, your max value of an Int will be 2147483647 by default. If a value of 2147483648 or more is assigned, the type will be changed to Int64.
There are different ways to check the size of the int and it's memory allocation.
Note: In Python 3, using the built-in type() method will always return <class 'int'> no matter what size Int you are using.
On my machine:
>>> print type(1<<30)
<type 'int'>
>>> print type(1<<31)
<type 'long'>
>>> print type(0x7FFFFFFF)
<type 'int'>
>>> print type(0x7FFFFFFF+1)
<type 'long'>
Python uses ints (32 bit signed integers, I don't know if they are C ints under the hood or not) for values that fit into 32 bit, but automatically switches to longs (arbitrarily large number of bits - i.e. bignums) for anything larger. I'm guessing this speeds things up for smaller values while avoiding any overflows with a seamless transition to bignums.
Interesting. On my 64-bit (i7 Ubuntu) box:
>>> print type(0x7FFFFFFF)
<type 'int'>
>>> print type(0x7FFFFFFF+1)
<type 'int'>
Guess it steps up to 64 bit ints on a larger machine.
Python 2.7.9 auto promotes numbers.
For a case where one is unsure to use int() or long().
>>> a = int("123")
>>> type(a)
<type 'int'>
>>> a = int("111111111111111111111111111111111111111111111111111")
>>> type(a)
<type 'long'>
It manages them because int and long are sibling class definitions. They have appropriate methods for +, -, *, /, etc., that will produce results of the appropriate class.
For example
>>> a=1<<30
>>> type(a)
<type 'int'>
>>> b=a*2
>>> type(b)
<type 'long'>
In this case, the class int has a __mul__ method (the one that implements *) which creates a long result when required.
From python 3.x, the unified integer libraries are even more smarter than older versions. On my (i7 Ubuntu) box I got the following,
>>> type(math.factorial(30))
<class 'int'>
For implementation details refer Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.c files. The last file is a dynamic module (compiled to an so file). The code is well commented to follow.
Just to continue to all the answers that were given here, especially #James Lanes
the size of the integer type can be expressed by this formula:
total range = (2 ^ bit system)
lower limit = -(2 ^ bit system)*0.5
upper limit = ((2 ^ bit system)*0.5) - 1

determine the type of a value which is represented as string in python

When I read a comma seperated file or string with the csv parser in python all items are represented as a string. see example below.
import csv
a = "1,2,3,4,5"
r = csv.reader([a])
for row in r:
d = row
d
['1', '2', '3', '4', '5']
type(d[0])
<type 'str'>
I want to determine for each value if it is a string, float, integer or date. How can I do this in python?
You could do something like this:
from datetime import datetime
tests = [
# (Type, Test)
(int, int),
(float, float),
(datetime, lambda value: datetime.strptime(value, "%Y/%m/%d"))
]
def getType(value):
for typ, test in tests:
try:
test(value)
return typ
except ValueError:
continue
# No match
return str
>>> getType('2010/1/12')
<type 'datetime.datetime'>
>>> getType('2010.2')
<type 'float'>
>>> getType('2010')
<type 'int'>
>>> getType('2013test')
<type 'str'>
The key is in the tests order, for example the int test should be before the float test. And for dates you can add more tests for formats you want to support, but obviously you can't cover all possible cases.
This cannot be done in a reliable manner and that is not due to limitations in Python or any other programming language for that matter. A human being could not do this in a predictable manner without guessing and following a few rules (usually called Heuristics when used in this context).
So lets first design a few heuristics then encode them in Python. Things to consider are:
All the values are valid strings we know that because that is the basis of our problem so there is no point in checking for this at all. We should check everything else we can whatever falls through we can just leave as a string.
Dates are the most obvious thing to check first if they are formatted in predictable manner such as [YYYY]-[MM]-[DD]. (ISO ISO 8601 date format) they are easy to distinguish from other bits of text that contain numbers. If the dates are in a format with just numbers like YYYYMMDD then we are stuck as these dates will be indistinguishable from ordinary numbers.
We will do integers next because all integers are valid floats but not all floats are valid integers. We could just check if the text contains on digits (or digits and the letters A-F if hexadecimal numbers are possible) in this case treat the value as an integer.
Floats would be next as they are numbers with some formatting (the decimal point). It is easy to recognise 3.14159265 as a floating point number. However 5.0 which can be written simply as 5 is also a valid float but would have been caught in the previous steps and not be recognised as a float even if it was intended to be.
Any values that are left unconverted can be treated as strings.
Due to the possible overlaps I have mentioned above such a scheme can never be 100% reliable. Also any new data type that you need to support (complex number perhaps) would need its own set of heuristics and would have to placed in the most appropriate place in the chain of checks. The more likely a check is to match only the data type desired the higher up the chain it should be.
Now lets make this real in Python, most of the heuristics I mentioned above are taken care of for us by Python we just need to decide on the order in which to apply them:
from datetime import datetime
heuristics = (lambda value: datetime.strptime(value, "%Y-%m-%d"),
int, float)
def convert(value):
for type in heuristics:
try:
return type(value)
except ValueError:
continue
# All other heuristics failed it is a string
return value
values = ['3.14159265', '2010-01-20', '16', 'some words']
for value in values:
converted_value = convert(value)
print converted_value, type(converted_value)
This outputs the following:
3.14159265 <type 'float'>
2010-01-20 00:00:00 <type 'datetime.datetime'>
16 <type 'int'>
some words <type 'str'>
There's no real answer to this as far as I can tell since these are just strings. They're not integers or floats or whatever. Those are roles you decide. eg. Is 1 an integer or a float?
A couple of things come to mind though. One is to do some kind of pattern matching (eg. If it contains a decimal point, it's a float etc.). For parsing/guessing dates, you can try this or this.
You could also try 'casting' the element into whatever you want and catch exceptions to try the others. You can do something like try int, if it fails, try float and if that fails, try date etc.
What you want to acheive is difficult because the types are ambiguous: "1" could either be a string, or an int for example. At any rate, you could try something like this:
Dates: presumably they are in a known format: if so, you can try instantiating a datetime from the timestamp string (datetime.strptime()) and if it fails you know its not a datetime.
Floats: ensure all characters are either a digit and there is at least one "." in the string. Then convert to float (float(value))
Integers: regex the string and match digits. Ensure the string is the same lenght as the source string then convert (int(value))
If none of the above worked, it's a string.
Well..you can't.
How would you decide if "5" is meant as a string or an integer?
How would you decide if "20100120" is meant as an integer or a date?
You can of course make educated guesses, and implement some kind of parse order. First try it as a date, then as a float, then as an int, and lastly as a string.
From the manual:
Return a reader object which will
iterate over lines in the given
csvfile. csvfile can be any object
which supports the iterator protocol
and returns a string each time its
next() method is called — file objects
and list objects are both suitable.
The interface requires that a string be returned each time next() is called.
The date is a bit harder. It depends on the format and how regular it is. Here is a clue to get you started on the rest.
>>> int('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'a'
>>> int('1')
1
>>> float('1')
1.0
>>> float('1.0')
1.0
But notice:
>>> int(1.0)
1

Categories