Search code examples
pythoninputintegeruser-inputliterals

`int('10**2')` raises `ValueError: invalid literal for int() with base 10: '10**2'` despite `type(10**2)` being `<class 'int'>`


int('10**2') raises ValueError: invalid literal for int() with base 10: '10**2' despite type(10**2) being <class 'int'>.

I take input n as n = input(), then I do int(n). When I input 10**2, I get ValueError: invalid literal for int() with base 10: '10**2'.

I'm guessing the issue is that 10**2 is not a literal - it has to be evaluated first, but I'm hesitant to do int(eval(n)) since n can be any string.


By contrast, float('1e2') despite being very similar, doesn't raise an error. I guess 1e2 is considered a literal...? and doesn't have to be evaluated?


My current workaround is to check whether the string contains '**' and if it does, handle it accordingly:

n = input()
if '**' in n:
  base, exp, *a = n.split('**')
  if a:
    raise ValueError(f'This input, {n}, can't be interpreted as an integer')
  n = int(base)**int(exp)
else:
  n = int(n)

or to support expressions like 3**3**3:

n = input()
if '**' in n:
  operands = input.split('**')
  # '**' associates to the right
  exp = 1
  while operands:
    base = int(operands.pop())
    exp = base ** exp
  n = exp
else:
  n = int(n)

Solution

  • Yes, 10**2 must be evaluated while 1e2 is a constant. I suggest taking a look at Evaluating a mathematical expression in a string for some options regarding parsing mathematical expressions in strings.