迭代可能是迭代器或单个元素的东西

时间:2016-04-20 16:45:26

标签: python python-3.x

假设我有以下功能:

def sum(summands)
    s = 0
    for a in summands:
        s = a + s

用户可以使用列表sum([1, 2, 3])来调用它,但如果您也可以使用数字sum(5)直接调用它,那将会很方便。 (它实际上并不是数字,只是一个简化的例子。)

我可以发明一个功能:

def make_iterable(x):
    # returns x if x is iterable, returns [x] if x is not iterable

但是,是否有一种更短的,内置的方法可以使单个元素可迭代?

5 个答案:

答案 0 :(得分:2)

这个怎么样。

def sum(summands)
    s = 0

    try:
        iter(summands)
    except TypeError:
        return summands

    for a in summands:
        s = a + s
    return s

或者,如果您想使用您提议的shell函数,可以将try: except:提取到make_iterable

Python 2.x:

def make_iterable(x):
    try:
        iter(x)
    except TypeError:
        x=[x]
    return x

Python 3.x:

def make_iterable(x):
    try: yield from x
    except TypeError: yield x

然后将其称为总和

def sum(summands)
    s = 0

    summands = make_iterable(summands)

    for a in summands:
        s = a + s
    return s

答案 1 :(得分:2)

您可以在函数内部检查它是否可迭代,如果不是,则将其包装在列表中。我相信collections.Iterable是一个很好的方法:

import collections

if isinstance(summands, collections.Iterable):
    tmp = summands
else:
    tmp = [summands]

答案 2 :(得分:1)

您可以检查它是否可迭代并将其设为一个(假设它不是字符串)。注意:sum是内置函数的名称,因此您可能不应该将自己的函数命名为同一个函数。请参阅PEP 8 - Style Guide for Python Code

import collections

def mysum(summand):
    if not isinstance(summand, collections.Iterable):
        summand = (summand,)
    elif isinstance(summand, str):
        raise TypeError('string argument not supported')
    s = 0
    for a in summand:
        s += a
    return s

print(mysum([1, 2, 3]))
print(mysum(42))
print(mysum("won't work"))

输出:

6
42
Traceback (most recent call last):
  File "iterate-over-something.py", line 18, in <module>
    print(mysum("won't work"))
  File "iterate-over-something.py", line 10, in mysum
    raise TypeError('string argument not supported')
TypeError: string argument not supported

答案 3 :(得分:0)

您可以测试它是列表还是int:

if isinstance(summand, list)
    sumlist(summand)
if isinstance(summand, int)
    Sumint(summand)

然后为每种类型编写求和函数。或者您可以使用列表组合将整数转换为列表&#39; summand = [x for x in range(summand +1)]并使用它。

答案 4 :(得分:0)

这就是你所需要的一切

def sum(summands)
s = 0
summands = summands if isinstance(summands, list) else [summands]
for a in summands:
    s = a + s