【问题标题】:Efficiently looping through lists in Python在 Python 中有效地循环列表
【发布时间】:2016-09-15 16:06:27
【问题描述】:

我需要创建一个 python 函数,给定有序列表 ab 返回 True .

这当然很容易通过使用这样的东西来完成:

for item in a:
  if (a+1 in b):
     return True

但是,我需要使其尽可能高效,因为该函数将用于处理大量数据。给我的提示是使用 iter()next() 操作,但我还没有找到一种方法来使用它们进行有效处理。有谁知道如何实现这些,或使用另一种快速算法? 提前致谢。

【问题讨论】:

  • 您可以将b 转换为一个集合,或者您可以订购它以更快地找到其中的内容。我不知道你为什么被告知使用iternext
  • 你的意思是for item in a: if item+1 in b: return True?如果b 很大,请将其设为集合而不是列表。
  • 这个列表是专门排序的,我应该利用这个事实来加快速度。
  • 如果可能,将a 转换为生成器函数。这将使您的代码更节省内存。只是循环遍历生成器中的列表无济于事。这里的用例是如果你从某个地方获取数据或以某种方式生成它wiki.python.org/moin/Generators
  • @wim 非建设性的。

标签: python list loops iterator


【解决方案1】:

我可以看到两个更有效的选项。

  1. 遍历a 中的每个元素,并对b 中的element+1 执行二进制搜索。

时间复杂度:O(n*log(m)),其中 n = |a| 和 m = |b|

    for element in a:
        if binary_search(a, element+1):
            return True
    return False
  1. 通过 [0,|a|) 和 [0,|b|) 增加两个计数器,例如 ij。当i 小于|a| 并且j 小于|b| 时循环。比较 a[i] + 1b[j]。如果它们相等,则返回True。如果a[i] + 1 > b[j] 的值增加j。否则,增加i

时间复杂度:O(n+m),其中 n = |a| 和 m = |b|

    i = 0
    j = 0
    while i < len(a) and j < len(b):
        if a[i] + 1 == b[j]:
            return True
        elif a[i] + 1 > b[j]:
            j += 1
        else:
            i += 1
    return False            

【讨论】:

  • 我认为我们有相同的算法,但我们的答案却完全不同。恕我直言,while 循环中的条件不完整:... and j &lt; len(b).
【解决方案2】:

警告:没有经过很好测试的代码。假设您编写的列表已排序。

iternext 提示背后的想法是,在一个循环中,您可以在一个或另一个列表中前进。如果第一个数字太小,请尝试下一个第一个数字。如果第二个太小,请尝试文本第二个数字。

def test1(a, b): 
    ia = iter(a)
    ib = iter(b)
    try:
        ea = next(ia)
        eb = next(ib)
        while True:
            print("debug: comparing {} -- {}".format(ea, eb))
            diff = ea - eb
            if diff == -1: 
                print("debug: OK!")
                return True
            elif diff < -1: 
                ea = next(ia)
            else:
                eb = next(ib)
    except StopIteration:
        print("debug: not found")
        return False

lista=[1,2,4,10,31,33,45,67]
listb=[7,16,22,29,34,39,49,59,60,100,200,300]
test1(lista, listb)

输出显示了工作中的算法:

debug: comparing 1 -- 7
debug: comparing 2 -- 7
debug: comparing 4 -- 7
debug: comparing 10 -- 7
debug: comparing 10 -- 16
debug: comparing 31 -- 16
debug: comparing 31 -- 22
debug: comparing 31 -- 29
debug: comparing 31 -- 34
debug: comparing 33 -- 34
debug: OK!

【讨论】:

    【解决方案3】:

    感谢两位的回答!我最终使用了您的解决方案的组合版本:

    a = iter(l1)
    b = iter(l2)
    i = next(a)
    j = next(b)
    try:
        while (i):
            if i + 1 == j:
                return True
            elif i + 1 > j:
                j = next(b)
            else:
                i = next(a)
    except StopIteration:
        return False
    

    【讨论】:

      猜你喜欢
      • 2021-07-31
      • 2022-01-19
      • 2017-11-14
      • 2013-09-13
      • 1970-01-01
      • 2019-04-29
      • 2015-05-07
      • 1970-01-01
      相关资源
      最近更新 更多