基本上,我希望能够将int,str,tuple和float分成两半。我在区分输入类型然后返回相同类型时遇到问题。
例如,一半(7)应该返回3(不是3.0!),一半(9.0)应该返回4.5,一半("十七和#34;)应该返回" seve",和一半((1,2,3,4,5,6,7))应返回(1,2,3)。我试过这段代码没有成功:
def half(x):
"""returns half of the input, rounded down
str -> str, int -> int, float -> float, tuple -> tuple"""
return int(x/2)
if x is float:
return float(x/2)
if x is tuple:
return tuple(x/2)
if x is str:
return str(x/2)
答案 0 :(得分:6)
只需使用functools.singledispatch
,它根据第一个参数的类型选择实现:
from functools import singledispatch
@singledispatch
def half(x):
raise TypeError()
@half.register(int)
def _(x):
return x // 2
@half.register(float)
def _(x):
return x / 2
@half.register(tuple)
def _(x):
return x[:len(x) // 2]
@half.register(str)
def _(x):
return x[:len(x) // 2]
如果您愿意,可以将此缩短为将lambdas传递给half.register
,而不是使用装饰器和函数语句:
from functools import singledispatch
@singledispatch
def half(x):
raise TypeError()
half.register(int, lambda x: x // 2)
half.register(float, lambda x: x / 2)
half.register(tuple, lambda x: x[:len(x) // 2])
half.register(str, lambda x: x[:len(x) // 2])
答案 1 :(得分:1)
首先,您需要检查类型。其次,此代码假定您使用的是Python 2。
def half(x):
if type(x) == float:
return x / 2
if type(x) == int:
return x // 2
if type(x) in (tuple, str):
return x[:len(x)//2]
答案 2 :(得分:1)
您可以使用类型为键的字典和lambda作为值,使用//
表示整数,使用/
表示浮点数,并简单地为str和元组len(x)//2
编制索引。
def half(i):
d = {float: lambda x: x/2, int: lambda x: x//2, str: lambda x: x[:len(x)//2:], tuple: lambda x: x[:len(x)//2]}
return d.get(type(i), lambda x: "Invalid input")(i)
In [29]: print(half(7))
3
In [30]: print(half((1,2,3,4,5,6,7)))
(1, 2, 3)
In [31]: print(half("seventeen") )
seve
In [32]: print( half(9.0))
4.5
答案 3 :(得分:1)
import numbers
def half(x):
if isinstance(x, numbers.Integral):
return x // 2
elif isinstance(x, numbers.Real):
return x / 2.
elif isinstance(x, (tuple, str)):
return x[:len(x) // 2]
else:
raise TypeError("x should be an int, float, tuple, or str (or derived from one of those)")