通过输入进行迭代的Pythonic方法,输入可以是字符串、列表或dict

通过输入进行迭代的Pythonic方法,输入可以是字符串、列表或dict,python,Python,我是编程新手,需要迭代输入元素。输入可以是字符串、列表(大部分)或dict。我编写了一些代码来检查给定的输入是字符串、列表还是dict等,但我想知道是否有更简单的方法来完成 例如,我检查如下: if isinstance(vlan, list): for i in vlan: <<do some operation here>> if isinstance(vlan, string): <<do some op

我是编程新手,需要迭代输入元素。输入可以是字符串、列表(大部分)或dict。我编写了一些代码来检查给定的输入是字符串、列表还是dict等,但我想知道是否有更简单的方法来完成

例如,我检查如下:

 if isinstance(vlan, list):
      for i in  vlan:
          <<do some operation here>>
 if isinstance(vlan, string):
      <<do some operation here>>
 if isinstance(vlan, dict):
      for i in vlan.keys()
         <<do some operation here>>
如果存在(vlan,列表):
对于vlan中的i:
如果isinstance(vlan,字符串):
如果存在(vlan、dict):
对于vlan.keys()中的i

这个操作我必须执行很多次(虽然我可以编写一个函数来扩展和发送元素,但我只是想知道是否有其他方法可以替代它)。

使用
elif
而不是
if

 if isinstance(vlan, list):
      for i in  vlan:
          <<do some operation here>>
 elif isinstance(vlan, str):
      <<do some operation here>>
 elif isinstance(vlan, dict):
      for i in vlan.keys():
         <<do some operation here>>
如果存在(vlan,列表):
对于vlan中的i:
elif isinstance(vlan、str):
elif isinstance(vlan、dict):
对于vlan.keys()中的i:
然后,假设“在此处执行某些操作”始终是同一件事,并且如果您获得一个字符串,您希望将该操作应用于一个字符串,如果您获得一个字符串集合,则应用于每个项目,只需事先将该字符串包装在一个列表中:

如果存在(vlan、str):
vlan=[vlan]
对于vlan中的i:
#在这里做些手术
通常会对str进行这种特殊的大小写/包装,特别是因为Python的字符串是可移植的,但通常希望将它们作为原子处理。

鉴于此:

这个手术我要进行很多次

我认为您的问题是关于如何避免在多个函数中重复此代码模式。答案或多或少取决于具体的用例——特别是“这里的dou-some-operation”是否适用于所有三种类型

在第一种情况下,围绕
map(func,iterable)
的简单通用包装器是显而易见的简单解决方案:

def mapply(func, iterable):
    # first weed out the special case
    if isinstance(iterable, str):
       iterable = [iterable]
    return map(func, iterable)
但是我假设您的用例稍微复杂一些,在“dou some_op”部分中有一些特定于类型的变化。在这种情况下,以下选项可能非常适合:

import abc

class BaseMapper(metaclass=abc.ABCMeta):
    def apply(self, obj):
        if instance(obj, list):
            return self._apply_list(obj)
        if isinstance(obj, str)
            return self._apply_str(obj)
        if isinstance(obj, dict):
            return self._apply_dict(obj)

     @abc.abstractmethod
     def _apply_list(self, obj):
         # handle a list
     @abc.abstractmethod
     def _apply_dict(self, obj):
         # handle a dict

     @abc.abstractmethod
     def _apply_str(self, obj):
         # handle a str

然后您只需将其子类化并实现抽象方法。

好的解决方案取决于每种类型的“执行某些操作”是什么。请添加更多详细信息。这是否回答了您的问题?例如,可以使用相同的代码对字符串、列表和字典进行迭代,而无需检查类型。这就是所谓的duck类型。
import abc

class BaseMapper(metaclass=abc.ABCMeta):
    def apply(self, obj):
        if instance(obj, list):
            return self._apply_list(obj)
        if isinstance(obj, str)
            return self._apply_str(obj)
        if isinstance(obj, dict):
            return self._apply_dict(obj)

     @abc.abstractmethod
     def _apply_list(self, obj):
         # handle a list
     @abc.abstractmethod
     def _apply_dict(self, obj):
         # handle a dict

     @abc.abstractmethod
     def _apply_str(self, obj):
         # handle a str