【问题标题】:Python type comparisionPython类型比较
【发布时间】:2012-07-23 12:24:08
【问题描述】:

好的,所以我有一个包含三个值的元组列表(code, value, unit)

当我要使用它时,我需要检查一个值是一个 str、一个列表还是一个矩阵。 (或检查是否列表,然后再次检查是否列表)

我的问题只是我应该这样做,还是有更好的方法?

for code, value, unit in tuples:
    if isinstance(value, str): 
        # Do for this item
    elif isinstance(value, collections.Iterable):
        # Do for each item
        for x in value:
             if isinstance(x, str):
                  # Do for this item
             elif isinstance(x, collections.Iterable):
                  # Do for each item
                  for x in value:
                      # ...
             else:
                  raise Exception
    else:
        raise Exception

【问题讨论】:

  • 外部for 循环的主体相当混乱。第一行不应该有x 而不是value 吗?内部循环不应该是for y in x吗?

标签: python instance dynamic-typing


【解决方案1】:

最好的解决方案是避免混合这样的类型,但如果你坚持使用它,那么你所写的就可以了,除非我只检查 str 实例。如果它不是字符串或可迭代的,那么无论如何你都会得到一个更合适的异常,所以不需要自己做。

for (code,value,unit) in tuples:
    if isinstance(value,str): 
        #Do for this item
    else:
        #Do for each item
        for x in value:
             if isinstance(value,str):
                  #Do for this item
             else:
                  #Do for each item
                  for x in value:

【讨论】:

    【解决方案2】:

    这可行,但每次调用isinstance 时,您都应该问自己“我可以向value 添加一个方法吗?”这会将代码更改为:

    for (code,value,unit) in tuples:
        value.doSomething(code, unit)
    

    为此,您必须将 str 之类的类型和列表包装在实现 doSomething() 的辅助类型中

    【讨论】:

    • 我实际上不会对值做任何事情,而是将值分配给 excelsheet。我相信像邓肯说的那样做对我来说更容易。
    【解决方案3】:

    另一种方法是将此代码分解为更通用的生成器函数(假设 Python 2.x):

    def flatten(x):
        if isinstance(x, basestring):
            yield x
        else:
            for y in x:
                for z in flatten(y):
                    yield y
    

    (这也包含了Duncan's answer 中建议和解释的简化。)

    现在,您的代码变得非常简单易读:

    for code, value, unit in tuples:
        for v in flatten(value):
            # whatever
    

    分解代码也有助于在代码中的多个位置处理这种数据结构。

    【讨论】:

      【解决方案4】:

      只需使用元组并捕获任何异常。跳之前不要看:)

      【讨论】:

      • 我想你的意思是,请求宽恕比请求许可更容易 :)
      【解决方案5】:

      递归会有所帮助。

      def processvalue(value):
        if isinstance(value, list): # string is type Iterable (thanks @sven)
          for x in value:
            processvalue(value)
        else:
          # Do your processing of string or matrices or whatever.
      
      
      # Test each the value in each tuple.
      for (code, value, unit) in tuples:
        processvalue(value)
      

      这是处理嵌套结构的一种更简洁的方法,并且还可以让您处理任意深度。

      【讨论】:

      • 在这种情况下,我知道二维数组是最大的,我必须对它们进行索引,使用这种方法可能更难
      • 我不明白你把它们编入索引是什么意思。
      猜你喜欢
      • 2018-01-21
      • 2021-03-03
      • 1970-01-01
      • 2012-09-14
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 2014-05-25
      • 1970-01-01
      相关资源
      最近更新 更多