限制循环条件

时间:2014-04-27 22:48:59

标签: python loops

我有一个列表,让我们说500,000个条目,每个条目都是(val1, val2)等元组。

目前,我循环遍历列表并在循环内部,我有一个条件,如:

if val2 == someval:
    do_something()
    break

但是,我想知道是否有更快的方法在特定条件下循环遍历元素,例如只循环遍历val2 == someval的项目,而不是整个列表然后进行检查。

6 个答案:

答案 0 :(得分:1)

从另一方拿走它怎么样:

if someval in lst:
  my_action(somewal)

在lst中对somewal成员资格的测试也需要一个循环,但是这在C中运行更优化的代码,因此它可能更快。

In [49]: x = 3

In [50]: %timeit x in [1, 2, 3]
10000000 loops, best of 3: 53.8 ns per loop

In [51]: %timeit x == 1 or x == 2 or x == 3
10000000 loops, best of 3: 85.5 ns per loop

In [52]: x = 1

In [53]: %timeit x in [1, 2, 3]
10000000 loops, best of 3: 38.5 ns per loop

In [54]: %timeit x == 1 or x == 2 or x == 3
10000000 loops, best of 3: 38.4 ns per loop

在这里你可以看到,对于数字来说,很快就会出现#34;在测试中,时间差是可以忽略的,但对于"之后的"测试会员资格的速度更快。

更真实的测量案例:具有500000个数字的范围,在中间测试数字的存在:

In [64] lst = range(500000)

In [65]: %%timeit
250000 in lst
   ....: 
100 loops, best of 3: 2.66 ms per loop

In [66]: %%timeit
for i in lst:
  if i == 250000:
    break
   ....: 
100 loops, best of 3: 6.6 ms per loop

使用成员资格测试x in lst

,所需时间降至40%

答案 1 :(得分:0)

我不太确定有更快的方法。在我看来,你必须首先在列表中找到“val2”,根据我的经验需要循环。

答案 2 :(得分:0)

例如,此代码将迭代循环并将打印val1 只有当val2 == someval。

for val1, val2 in some_list:
    if val2 != someval:
        continue
    print val1

答案 3 :(得分:-1)

你似乎在问两个不同的问题。第一次你看到某些东西等于某个东西你就会破坏,另一个你只看那些等于某些东西的东西。对于后者,即:

“但是,我想知道是否有更快的方法在某个条件下循环遍历元素,例如只循环遍历val2 == someval的项目,而不是整个列表然后进行检查。”

你可以这样做:

for i in filter(lambda t: t[1] == someval, val_list):
    stuff

或通过列表理解:

for i in [x for x in val_list if x[1] == someval]:
    stuff

我的猜测是其中一个更快。

答案 4 :(得分:-1)

你必须“看到”列表中的所有元素才能决定是否在任何点val2 == someval并且你的列表没有按元组中的第二个值排序,因此循环遍历所有元素可以不可避免。

但是,您可以确保用于循环列表的方法尽可能高效。例如,您可以 使用for statement来过滤掉满足val2 == someval然后do something的值,而不是使用list comprehensions列表不是空的。我说“可能”,因为它实际上取决于数据的分布;是否对val2 == someval保持为真并执行某些操作等所有值都有用。

如果您使用的是Python 3.x,那么"list comprehensions and generator expressions in Python 3 are actually faster than they were in Python 2"

答案 5 :(得分:-1)

  1. 无法避免循环或if;答案表明有一种更快的方法是错误的; filter和列表推导将一点点改善问题;实际上,除非你使用生成器表达式(懒惰地评估),否则理解(以及filter)将使这(可能更多)更慢并且消耗内存。并且生成器表达式也不会改善性能。

  2. 除了用C或Java等语言或使用PyPy或Cython重写之外,没有办法让它更快。 for x in ...: if x ...: do_smth()已经是最快的方式了。当然,根据您的数据,您实际上可以以一种始终排序的方式构建数据结构(具有500,000个项目),因此您可能只需要遍历列表的开头。或者可能将满足特定条件的项目收集到单独的列表/集合/诸如此类中,这将在以后通过完全避免过滤和完整循环迭代产生非常好的结果。