I need a function that checks whether an input list is made all of number. I am aware of other solutions but what I am looking for is a bit different. The input of the function is a tuple provided using *args, and I need the function to work with lists, as well as with numbers. Furthermore it must catch also numbers written as string.
this means it must works for the following inputs:
- instance = CheckNumbersType([1,2,3,4,5,...])
- instance = CheckNumbersType(['1','2','3','4','5',...])
- instance = CheckNumbersType(1,2,3,4,5,...)
- instance = CheckNumbersType('1','2','3','4','5',...)
Here is my code, it works but I do not think it is very efficient and it looks also a bit pedantic to me. Is there any library or oyu have any other idea to avoid nesting all the if...else
and try...except
?
class CheckNumbersType:
def __init__(self, *args):
self.values = args
def isfloat(self):
var = None
check = True
for item in self.values:
if type(item) == list:
for value in item:
try:
float(value)
var = True
except ValueError:
var = False
print(var)
else:
try:
float(item)
var = True
except ValueError:
var = False
check = check and var
return check
CodePudding user response:
Using recursion is often a good way to deal with lists, especially if you might also have lists of lists. You should define this as a separate function that takes a single argument. If you need it within a class, then just call this function from within the class method, and you can then use is_floats(args)
to pass the arguments as a single argument. Function arguments are given in a tuple, so it is convenient to allow the function to accept tuples as well as lists.
def is_floats(x):
""" True if x is convertible to a float, or is a list or tuple (or nested list or
tuple) of values that are all convertible to floats """
if isinstance(x, (list, tuple)):
return all(is_floats(item) for item in x)
try:
float(x)
return True
except ValueError:
return False
CodePudding user response:
3 points:
I take you can stop once you find 1 non float element
You can flatten the input list before processing it
I still think
try...except
is the best way to assess if an input is afloat
or anint
from functools import reduce def flatten(l): def func(x): return x if type(x) is list else [x] return reduce(lambda x,y:func(x) func(y), l) def is_float(item): try: float(item) return True except ValueError: return False def is_float_list(my_list): for item in flatten(my_list): if not is_float(item): return False return True print(is_float_list([1,2,3,4])) # returns True print(is_float_list([1,2,3,'A'])) # returns False print(is_float_list([[1,2,3],['2', 3, '4']])) # returns True print(is_float_list([[1,2,3],['2', 3, '4']])) # returns False print(is_float_list([[1,2,3],10,['2', 3, '4']])) # returns True print(is_float_list([[1,2,3],'A',['2', 3, '4']])) # returns False
CodePudding user response:
You could try:
def CheckNumbersType(*args):
l = list(args) if not isinstance(args[0], list) else args[0]
try:
for e in l:
float(e)
except ValueError:
return False
return True
In which:
- First line:
- *args is a tuple of the args to the function
- if the args[0] is not a list 'cast' it to a list else keep it as
- Loop in a try structure, to test if each element can be converted to a float (ints convert to floats)
CodePudding user response:
You don't need to use the try/except structure on every item. Just try to convert the whole list of parameters in one step. The exception will occur on individual items just the same. Use recursion to handle lists of values in addition to the variable parameter tuple:
def CheckNumbersType(*numbers):
try:
return all(CheckNumbersType(*n) if isinstance(n,list) else [float(n)]
for n in numbers)
except (ValueError,TypeError):
return False