代码之家  ›  专栏  ›  技术社区  ›  m0j0

在Python中搜索对象列表

  •  135
  • m0j0  · 技术社区  · 17 年前

    class Data:
        pass
    
    myList = []
    
    for i in range(20):
        data = Data()
        data.n = i
        data.n_squared = i * i
        myList.append(data)
    

    我该如何搜索myList列表以确定它是否包含n==5的元素?

    我一直在谷歌上搜索Python文档,我想我可以通过列表理解来做到这一点,但我不确定。顺便说一句,我必须使用Python 2.4.3,所以我无法使用任何新的gee-whiz 2.6或3.x功能。

    11 回复  |  直到 9 年前
        1
  •  160
  •   Ali Afshar    17 年前

    你可以得到一个列表 全部 将元素与列表理解进行匹配:

    [x for x in myList if x.n == 30]  # list of all elements with .n==30
    

    如果你只是想确定列表是否包含 匹配元素并(相对)高效地完成它,你可以做到

    def contains(list, filter):
        for x in list:
            if filter(x):
                return True
        return False
    
    if contains(myList, lambda x: x.n == 3)  # True if any element has .n==3
        # do stuff
    
        2
  •  86
  •   h3xStream    12 年前

    简洁、优雅、强大:

    any(x for x in mylist if x.n == 10)
    

    使用Python any() 内置,定义如下:

    -> 如果可迭代对象的任何元素为True,则返回True。相当于:

    def any(iterable):
        for element in iterable:
            if element:
                return True
        return False
    
        3
  •  52
  •   Charlie Martin    17 年前

    为了完整起见,我们不要忘记可能奏效的最简单的事情:

    for i in list:
      if i.n == 5:
         # do something with it
         print "YAY! Found one!"
    
        4
  •  46
  •   Markus Jarderot    7 年前
    [x for x in myList if x.n == 30]               # list of all matches
    [x.n_squared for x in myList if x.n == 30]     # property of matches
    any(x.n == 30 for x in myList)                 # if there is any matches
    [i for i,x in enumerate(myList) if x.n == 30]  # indices of all matches
    
    def first(iterable, default=None):
      for item in iterable:
        return item
      return default
    
    first(x for x in myList if x.n == 30)          # the first match, if any
    
        5
  •  39
  •   vartec    17 年前
    filter(lambda x: x.n == 5, myList)
    
        6
  •  9
  •   Markus Jarderot    17 年前

    您可以使用 in 在集合中查找项目,并使用列表理解来提取您感兴趣的字段。这(适用于列表、集合、元组和任何定义 __contains__ __getitem__ ).

    if 5 in [data.n for data in myList]:
        print "Found it"
    

    另请参见:

        7
  •  5
  •   Johannes Weiss    17 年前

    另一种方法是使用next()函数。

    matched_obj = next(x for x in list if x.n == 10)
    
        8
  •  3
  •   dan-gph    17 年前

    __eq__ 以及a __hash__ Data 类,它可以检查是否 __dict__ 属性是相等的(相同的属性),然后如果它们的值也是相等的。

    如果你这样做了,你可以使用

    test = Data()
    test.n = 5
    
    found = test in myList
    

    in 关键字检查是否 test myList .

    如果你只想a n 财产在 您可以使用:

    class Data(object):
        __slots__ = ['n']
        def __init__(self, n):
            self.n = n
        def __eq__(self, other):
            if not isinstance(other, Data):
                return False
            if self.n != other.n:
                return False
            return True
        def __hash__(self):
            return self.n
    
        myList = [ Data(1), Data(2), Data(3) ]
        Data(2) in myList  #==> True
        Data(5) in myList  #==> False
    
        9
  •  3
  •   m0j0    6 年前

    考虑使用字典:

    myDict = {}
    
    for i in range(20):
        myDict[i] = i * i
    
    print(5 in myDict)
    
        10
  •  0
  •   Tomerikoo Glorified    4 年前

    index 方法:

    data_n = 30
    j = [data.n for data in mylist].index(data_n)
    print(mylist[j].data.n == data_n)