When to use ast.literal_eval

If it's going to be used as an int, then just use:

cypher_key = int(input("Enter the key (a value between 0 and 25) : "))

Only use that if you expect the user to be entering 10e7 or something. If you want to handle different bases, you can use int(input(...), 0) to automatically divine the base. If it really is an integer value between 0 and 25, there's no reason to use ast.


When to use it.

ast.literal_eval(input()) would be useful if you expected a list (or something similar) by the user. For example '[1,2]' would be converted to [1,2].

If the user is supposed to provide a number ast.literal_eval(input()) can be replaced with float(input()), or int(input()) if an integer is expected.


Performance

Note that premature [micro-]optimization is the root of all evil. But since you asked:

To test the speed of ast.literal_eval(input()) and float(input() you can use timeit.

Timing will vary based on the input given by the user.

Ints and floats are valid input, while anything else would be invalid. Giving 50% ints, 40% floats and 10% random as input, float(input()) is x12 faster.

With 10%, 10%, 80% and float(input()) is x6 faster.

import timeit as tt

lst_size = 10**5

# Set the percentages of input tried by user.
percentages = {'ints': .10,
               'floats': .10,
               'strings': .80}
assert 1 - sum(percentages.values()) < 0.00000001

ints_floats_strings = {k: int(v*lst_size) for k, v in percentages.items()}

setup = """
import ast

def f(x):
    try:
        float(x)
    except:
        pass

def g(x):
    try:
        ast.literal_eval(x)
    except:
        pass

l = [str(i) for i in range({ints})]
l += [str(float(i)) for i in range({floats})]
l += [']9' for _ in range({strings}//2)] + ['a' for _ in range({strings}//2)]
""".format(**ints_floats_strings)

stmt1 = """
for i in l:
    f(i)
"""

stmt2 = """
for i in l:
    g(i)
"""


reps = 10**1
t1 = tt.timeit(stmt1, setup, number=reps)
t2 = tt.timeit(stmt2, setup, number=reps)

print(t1)
print(t2)

print(t2/t1)

Tags:

Python 3.X