用 str、float、int 和元组除法

Division with str, float, int, and tuples

基本上,我希望能够将 int、str、tuple 和 float 分成两半。我在区分输入类型然后 returning 相同类型时遇到问题。

例如,half(7) 应该 return 3(不是 3.0!),half(9.0) 应该 return 4.5,half("seventeen") 应该 return "seve",而 half((1,2,3,4,5,6,7)) 应该 return (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)

只需使用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]

如果您愿意,可以将其缩短为将 lambda 传递给 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])

首先你需要检查类型。其次,此代码假定您使用的是 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]

您可以使用类型为键和 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
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)")