【问题标题】:run for loop limited iterations in python在python中运行循环有限迭代
【发布时间】:2011-10-18 08:38:04
【问题描述】:

我有一个非常大的对象列表,我需要找到所有具有相同属性 (any_object.any_attribute) 的对象,然后将它们附加到一个新列表中。所以我已经对它们进行了预排序并运行了二进制搜索算法。 我找到了具有匹配属性的对象,但问题是这样的对象不止一个(它们是邻居),但我无法找到一种在这些连续对象上运行循环的干净方法,以便它们都可以附加。我的代码粘贴在下面。

  low   = 0
  high  = len(sortedObjects)
  while low < high:
    mid = (low + high)/2
    if sortedObjects[mid].attr < desired_attr:
      low = mid + 1
    elif sortedSamples[mid].attr > desired_attr:
      high = mid
    else:
      newList.append(sortedObjects[mid])
      break

所以我需要在最后一个 else 块中编写一些新代码,该代码将遍历所有具有相同属性的对象并附加它们。听起来需要一个 for 循环,但是否可以像在 C 中那样为有限的迭代运行一个 for 循环?

我不想遍历整个列表,因为这样会比较慢,而且这个脚本的要求之一是它必须快速高效。它将在非常大的数据集上运行,我们正在研究 10-12 小时的执行时间。提前致谢!

【问题讨论】:

    标签: python for-loop


    【解决方案1】:

    试试这个:

    else:
        # Find the first element that matches
        while mid > 0 and sortedSamples[mid - 1].attr == desired_attr:
            mid -= 1
    
        # Iterate until an element that doesn't match is found.
        while mid < len(sortedSamples) and sortedSamples[mid].attr == desired_attr:
            newList.append(sortedObjects[mid])
            mid += 1
    

    这在 O(m) 时间内运行,其中 m 是具有所需属性的对象的数量。

    【讨论】:

      【解决方案2】:

      如果您要更频繁地执行此搜索,请创建此属性的列表:

      attr_list = [o.attr for o in sortedObjects]
      

      然后使用bisect 模块:

      import bisect
      left_i = bisect.bisect_left(attr_list, desired_attr)
      right_i = bisect.bisect_right(attr_list, desired_attr, left_i)
      newList = sortedObjects[left_i:right_i]
      

      【讨论】:

        【解决方案3】:

        在 else 块中运行第二个循环,在其中减少 mid 直到找到第一个对象,然后向前循环以获取所有对象。您可以通过保存旧的mid 并在“向后循环”中找到它们时保存元素来加快速度,然后在向前循环之前再次向前跳转。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-10-14
          • 2016-07-06
          • 2016-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 2014-10-31
          相关资源
          最近更新 更多