【问题标题】:Python from a list of objects return the first object which has a class attribute setPython 从对象列表返回第一个具有类属性集的对象
【发布时间】:2015-10-27 22:08:38
【问题描述】:

给定具有属性 a 和 b 的对象列表,我想从列表中满足给定约束的第一个对象中获取属性。下面显示了一种解决方案,但对于具有许多属性的对象,这是不可取的。

class Foo(object):
  def __init__(self):
  self.a = 0
  self.b = 1

def get_first_a(l):
  return next(val.a for val in l if val.a > 0)

def get_first_b(l):
  return next(val.b for val in l if val.b > 0)

def main():
  bar0 = Foo()
  bar1 = Foo()
  bar2 = Foo()
  bar2.a = 10
  l = [bar0, bar1, bar2]
  a = get_first_a(l)  # returns 10
  b = get_first_b(l)  # returns 1

有没有办法将对象属性传递给函数?我不希望添加枚举或使用字符串匹配,而是类似于以下内容:

def get_first_b(l, object_attribute):
  return next(val.object_attribute for val in l if val.object_attribute != 0) 

【问题讨论】:

  • 你可以使用 python exec 编辑:@Pynchia 有一个更好的解决方案 getattr

标签: python list class attributes


【解决方案1】:

您可以使用 getattr,但如果没有满足您条件的 object_attribute,您最终会出现 StopIteration 错误:

def get_first(l, object_attribute, op, cond):
    return next((getattr(val, object_attribute) for val in l
                if op(getattr(val, object_attribute), cond)), None)

你可以将任何你喜欢的东西传递给单个函数:

from operator import ne, gt, lt
def main():
    bar0 = Foo()
    bar1 = Foo()
    bar2 = Foo()
    bar2.a = 10
    l = [bar0, bar1, bar2]
    a = get_first(l,"a", gt, 0)  # returns 10
    b = get_first(l, "b", ne, 0)  # returns 1
    c = get_first(l, "b", lt, -1)
    print(a)
    print(b)
    print(c)

main()

输出:

10
1
None

【讨论】:

    【解决方案2】:

    使用getattr 并为任何属性定义一个函数

    def get_first(l,attr):
      return next(getattr(val,attr) for val in l if getattr(val,attr) > 0)
    

    【讨论】:

      【解决方案3】:

      如果您知道对象中有哪些属性,请尝试以下操作:

      # some class with properties
      class Foo:
          def __init__(self, a, b):
              self.a = a
              self.b = b
      
          def retA(self):
              return self.a
      
          def retB(self):
              return self.b
      
      # forming a list with the objects
      l_b = []
      l_b.append(Foo('a1','b1'))
      l_b.append(Foo('a2','b2'))
      l_b.append(Foo('a3','b3'))
      
      # function to grab a property from object in list on the exact position in the list        
      def getPropFormListOfObj(list_obj, position_in_list, property_obj):
      """
      list_obj (type = list)- list of objects
      position_in_list (type = int) - position of object in the list from 0 to (len(list_obj) - 1)
      property_obj (type = str) - the property we want to return. in this implementation works only if == 'a' or 'b'
      """
          if (property_obj == 'a'):
              return list_obj[position_in_list].retA()
          elif (property_obj == 'b'):
              return list_obj[position_in_list].retB()        
      
      # test
      # expected output "a1"
      print getPropFormListOfObj(l_b, 0, 'a')
      
      # test
      # expected output "b2"
      print getPropFormListOfObj(l_b, 2, 'b')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-19
        • 1970-01-01
        • 2021-03-01
        • 2013-05-26
        • 2014-03-15
        • 1970-01-01
        • 2020-07-16
        相关资源
        最近更新 更多