0

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.

Ondrej K.
  • 8,841
  • 11
  • 24
  • 39
MikeMEiL
  • 3
  • 1
  • 1
  • 5
  • [Possible duplicate](https://stackoverflow.com/questions/33519688/converting-list-of-long-ints-to-ints) – Lomtrur Feb 09 '18 at 11:53
  • @Lomtrur No, that's different. The problem here is [this](https://docs.python.org/2/library/functions.html#int): *"If the argument is outside the integer range, the function returns a long object instead."* – tripleee Feb 09 '18 at 12:03
  • @tripleee But arn't ints in python at least 32 bits long? The numbers in the example don't reach that length – FlyingTeller Feb 09 '18 at 12:06
  • I've been wondering the same thing, but if that' what the OP is reporting, I'm guessing they are on a platform where the `int()` range is smaller than on mine. – tripleee Feb 09 '18 at 12:06
  • @tripleee I think I found my mistake: the int types are of course signed, so the maximal positive value will be 2^31-1, which is smaller than the numbers OP is using – FlyingTeller Feb 09 '18 at 12:10
  • I cannot reproduce that: `FromBus[1][0][1:5]` -> `[3724637724L, 3724837324L, 3724837707L, 3724837707L]` then `[int(i) for i in FromBus[1][0]][1:5]` -> `[3724637724, 3724837324, 3724837707, 3724837707]`. (Python 2.7.14, x86_64, Linux) But in any case, as long as your other use is still in Python, I am not sure why or what would be a problem using `long`. Also check `sys.maxint` to see size of `int` on your platform. – Ondrej K. Feb 09 '18 at 12:12
  • All I need is to get rid of the L at the end (I have to do mapping of two data frames later on by a column names and they have to be exact), I was just wondering what might be the cause of the problem of keeping it as "long" all the time. I can definitely go for solution using string convertion. edit: indeed, sys.maxint does show value lower than I am trying to keep under integer! – MikeMEiL Feb 09 '18 at 12:16
  • Then go with what tripleee says. You only see the the `L` when doing `repr(n)` but `str(n)` formatting shows just the number long or not. If you compare strings, make sure `str` and not `repr` is used. Or convert the other side and compare `int`(s)/`long`s. – Ondrej K. Feb 09 '18 at 12:36
  • One more thing. `int` and `long` really have the same interfaces so you shouldn't care in most of the cases. And in Py3 there is just `int` even for numbers wider then your platform's `int`. – Ondrej K. Feb 09 '18 at 12:38

3 Answers3

3

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.

tripleee
  • 175,061
  • 34
  • 275
  • 318
1

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.

Tatarize
  • 10,238
  • 4
  • 58
  • 64
0
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**
dsgdfg
  • 1,492
  • 11
  • 18