如果循环变量可以是数字或字符串或列表,是否有更好的方法来编写 for 循环?
例如一个原始代码:
foo(x)
x 取一个数字 ex: 7,或一个字符串 ex:'hello'。
为了在向后兼容的同时升级代码以获取列表(或 range() ),我首先检查类型:
if type(x) != list and type(x) != range:
x = [x]
for i in x:
foo(i)
想知道有没有更好的方法或功能来处理这种情况而不检查类型?
一般来说,您希望避免检查特定类型。相反,检查behavior.
在这种情况下,您可能想要检查
x
是否是 iterable,但也不是 str
.
from collections.abc import Iterable
if isinstance(x, Iterable) and not isinstance(x, str):
it = x
else:
it = (x,)
for i in it:
foo(x)
请注意,一个类不需要显式继承
Iterable
ABC 才能通过 isinstance
检查。任何遵循可迭代协议的类都被视为 Iterable
的“虚拟子类”,用于 isinstance
检查。
if not isinstance(x, (list, range)):
x = [x]
for i in x:
foo(i)
例如,如果你有一个嵌套列表并且你想要检查,以确保它确实是一个列表,然后检查嵌套在该列表内的数据,我会使用下面的类。您始终可以在列表推导式(在
__call__
内)中添加数据类型以进行检查。如果您的数据不是列表,我不确定您想做什么,所以我让您自己决定。希望对您有所帮助。
class SomeName:
def _foo(self, val):
return print(val)
def __call__(self, data):
if type(data) == list:
# add more types to the list to check against
return [self._foo(i) for i in data if type(i) in [list]]
else:
#not sure what you want here, so please change
return data
values = [1, 'a', [2, 3, 6, 'b'], 'hello', 3, 4, 5]
myInstance = SomeName()
myInstance(values)
输出:
[2, 3, 6, 'b']