有条件地进入for循环

时间:2018-09-28 12:21:29

标签: python for-loop

如果参数是一个序列(列表,元组),或者避免仅执行一次操作,则如何避免代码重复循环?

def foo(arg1,sequence=None):
    # If possible, loop, else do it once
        if isinstance(sequence,(list,tuple)):
            for value in sequence:
                do_something(arg1)
        else:
            do_something(arg1)

我在for循环中执行的操作要比此方法更长,并且我想知道您通常使用哪种方法来避免这种情况(如果您确实避免了这种情况)。我经常遇到这个问题,但我还没有想出办法解决它。

编辑:如所建议的,问题不是In Python, how do I determine if an object is iterable?的重复项。我不想引入其他条件。我想避免重复。

4 个答案:

答案 0 :(得分:6)

标准化默认情况下的循环,然后将单个情况转换为可迭代的情况:

if not isinstance(sequence, (list, tuple)):
    sequence = [sequence]

for value in sequence:
    do_something(value)

答案 1 :(得分:3)

我能想到的另一种合理的方法是将所有内容转换为序列,然后无条件地进行迭代。这在Python代码中相对较常见,并且通常被提取到辅助函数中。

$arr = ['car' => 'black', 'home' => 'white', 'train' => 'gold'];

答案 2 :(得分:3)

软件设计的角度来看,将其分为两个功能可能很有趣:

  1. 一个使某事物不是列表或元组(或其他事物)时使之迭代的函数,例如通过将其包装到列表或元组中;和
  2. 一个函数,它在我们使它成为可迭代对象之后对其进行迭代,并进行处理,例如:
def make_iterable(iterable):
    if not isinstance(iteable, (list,tuple)):
        return (iterable, )
    return iterable

def foo(arg1 ,sequence=None):
    for item in make_iterable(sequence):
        do_something(arg1, item)

因此,现在我们可以轻松地使更多的事情迭代。例如,我们可能返回一个None的空元组,以允许使用None作为避免迭代的一种方式:

def make_iterable(iterable):
    if iterable is None:
        return ()
    if not isinstance(iteable, (list,tuple)):
        return (iterable, )
    return iterable

在所有允许输入单个对象和可迭代对象的方法中,重用上述方法也很容易。

但是请注意,上述内容可能会有一些问题。有些类型是可迭代的,但实际上并不是您要迭代的项:例如,str迭代是可迭代的(您可以迭代其字符)。在这种情况下,In Python, how do I determine if an object is iterable?将成功,但是“解压缩”字符串可能不是一个好主意。但是,当您将其称为foo(4, 'foobar')时,您可能不想遍历该字符串,而是将其视为单个元素。

答案 3 :(得分:1)

常见的python方法是“请求宽恕而不是许可”。也就是说,尝试将其视为可迭代的,并且如果失败,则假设它不是

try:
    for value in sequence:
         do_something(arg1)
except TypeError:
    do_something(arg1)

我知道,当您来自另一种语言时,这似乎违反直觉,但这是在python中实现的一种常见方法。