Reputation: 3147
I frequently need to enter large integers for indexing and creating numpy arrays, such as 3500000 or 250000. Normally I'd enter these using scientific notation, 3.5e6 or .25e6 or such. This is quicker, and much less likely to have errors.
Unfortunately, python expects integer datatypes for indexing. The obvious solution is to convert datatypes. So [5e5:1e6]
becomes [int(5e5):int(1e6)]
, but this decreases readability and is somewhat longer to type. Not to mention, it's easy to forget what datatype an index is until an indexing operation fails on a list
or numpy.ndarray
.
Is there a way to have numpy
or python interpret large floats as integers, or is there an easy way to create large integers in python?
Upvotes: 1
Views: 709
Reputation: 719
My cheap solution is to create a helper function in proper scope.
def e(coeff, exponent):
return int (coeff * 10 ** exponent)
np_array[e(3.5,6)] # use like this
But this cheaper answer may cause round off error, Create alias for int in proper scope is simple and clean solution.
e=int # in proper scope
Upvotes: 2
Reputation: 3147
This should fix the problems with indexing lists and arrays with floats,
slice_orig = slice
def slice(*args):
return slice_orig(*[int(i) for i in args])
slice.__doc__ = slice_orig.__doc__+ """
WARNING: overridden to convert (stop, start, step) to integers"""
It doesn't allow using large numbers with other numpy
functions requiring an int
type.
EDIT: This has to be used explicitly, such as list[slice(1e5)]
, so it's not as useful as I expected.
Upvotes: 0
Reputation: 1975
You can add a shorter name to int()
such as I
I = int
x = I(3.5e6)
print (x)
#3500000
This still allows use of int()
normally
Upvotes: 0
Reputation: 28606
In a comment you considered having e5 = 10**5
for use as in 35*e5
, lamenting it doesn't support 3.5*e6
. Here's a hack that does:
class E:
def __init__(self, e):
self.val = 10**e
def __rmul__(self, x):
return int(x * self.val)
Demo:
>>> e6 = E(6)
>>> 3.5*e6
3500000
Though due to floats being lossy, this can lead to slight inaccurracies, for example:
>>> 0.1251*e6
125099
Here's a better hack, building the literal '0.1251e6'
and evaluating that:
class E:
def __init__(self, e):
self.e = e
def __rmul__(self, x):
return int(float('%se%d' % (x, self.e)))
Demo:
>>> e6 = E(6)
>>> 0.1251*e6
125100
Upvotes: 2
Reputation: 763
I can propose to use such notation [5*10**5:1*10**6]
but it's not so clear as in case of 5e5 and 1e6. And even worse in case of 3.5e6 = 35*10**5
Upvotes: 1
Reputation: 28606
If you're worried about mistakes in the number of zeros, try underscores.
>>> 3_500_000
3500000
Upvotes: 2