如果参数是一个序列(列表,元组),或者避免仅执行一次操作,则如何避免代码重复循环?
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?的重复项。我不想引入其他条件。我想避免重复。
答案 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)
从软件设计的角度来看,将其分为两个功能可能很有趣:
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中实现的一种常见方法。