2017-06-19 70 views
7

我试图运行一个for循环的python程序,它有一个变量,我每次从1增加到1的列表长度。在Java中,我的代码,我要为可能是这个样子:有没有办法在Python中影响范围计数器?

for (int i = 0; i < array.length; i++) { 
     //code goes here 
     i += //the number i want it to go up by 
} 

这实际上影响了我的柜台的方式意,让我能够有效跳过数字在我的for循环,我想尝试运行一个类似的程序,但在Python中。有没有办法用python的内置功能来做到这一点,或者如果我希望python以这种方式工作,我必须使用while循环和计数器来模拟这个吗?

回答

4

你需要为这个while循环:

i = 0 
while i < len(myArray): 
    # do stuff 
    if special_case: i+= 1 
    i += 1 
1

不能修改步骤中期数,但如果单步调试是恒定的,你可以在开始指定:

# the default 
>>> range(1, 10) 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

# step 2 
>>> range(1, 10, 2) 
[1, 3, 5, 7, 9] 

您也可以倒退:

>>> range(10, 0, -1) 
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

可悲的是,如果你的情况不是在整个迭代中步长恒定的情况下,你肯定需要一个while循环,正如你正确猜测的那样。

+0

我认为OP想要在执行过程中动态地影响循环变量 - 不是静态地改变循环结构 – inspectorG4dget

+0

@ inspectorG4dget这是一个选项,如果情绪虽然,ctation是不变的。编辑。 –

1

在蟒蛇是与Java非常相似。你可以根据不同的条件动态增加你的计数器,如下:

x = 1 
while x < 100: 
    if condition1: 
     x += 1 
    elif condition2: 
     x += 2 
    else: 
     x += 3 
0

你会对while循环感到高兴。 你可以做这样的事情

l = list(range(min_count,max_count)) 
for i in l: 

,并在循环过程修改l。但要做到这一点很困难。 您也可以使用skip方法创建迭代对象,并在循环过程中调用该对象。

class SkipRange: 

    def __init__(self, minc, maxc, step): 
     self.count = minc 
     self.maxc = maxc 
     self.step = step 

    def __iter__(self): return self 

    def __next__(self): 
     if self.count > self.maxc: raise StopIteration 
     c = self.count 
     self.count += self.step 
     return c 

    def skip(self, num = 1): self.count += num 

未经测试,完全脱离了bmy头的顶部;对于任何恼人的人来说,调试都是一个练习,而循环到足够的路线。我认为这更能说明封面上发生了什么。

s = SkipRange(min_count,max_count) 
for i in s: 
    # do stuff 
    s.skip(3) #skip next 3 items 

但是while循环更具可读性,在大多数情况下更容易。

1

在Python中,您可以使用内置的iter函数创建单向迭代器。有了这个,你可以拨打next有效地跳过一个步骤。

要使用多个步骤做到这一点,迭代工具recipies定义consume功能:

def consume(iterator, n): 
    "Advance the iterator n-steps ahead. If n is none, consume entirely." 
    # Use functions that consume iterators at C speed. 
    if n is None: 
     # feed the entire iterator into a zero-length deque 
     collections.deque(iterator, maxlen=0) 
    else: 
     # advance to the empty slice starting at position n 
     next(islice(iterator, n, n), None) 

在这种情况下,我们可以这样做:

import itertools 

def skip(iterator, n): 
    next(itertools.islice(iterator, n, n), None) 

range_iter = iter(range(len(ls))) 

for i in range_iter: 
    # ... 
    if custom_condition: 
     skip(range_iter, 2) # Or any number. 

这也适用于直接遍历列表:

ls_iter = iter(ls) 

for i in ls_iter: 
    # ... 
    if custom_condition: 
     skip(ls_iter, 3) 

由于它们使用内置类型和函数,因此它们非常高效。

2

(免责声明:从来不使用这个代码的任何远程严肃的目的)

在你的代码修改的i的价值问题是这样的:通常情况下,分配(包括增量赋值,+=)当地制造不变的值只在本地范围内可见。 range的内部不在本地范围内。当您重新分配i时,range实现无法知道这一点。

通常情况下。

但是Python有一个名为inspect的内置模块,它公开了有关您的程序的各种信息,而这些信息在运行时通常不会公开。这包括框架中变量的值,否则这些变量将完全无法访问。

违反良好的编程原则和自然规律,我们可以编写一个类似范围的函数,它穿透无知的面纱,并从调用上下文中盗取i的值,就像普罗米修斯如何从奥林匹斯山的高峰。 (注:还记得那个故事的结尾会发生什么普罗米修斯)

import inspect 
import re 

def mutable_range(max): 
    x = 0 
    while x < max: 
     yield x 
     record = inspect.stack()[1] 
     frame = record[0] 
     source_lines = record[4] 
     iterator_name = re.match(r"\s*for (\w+) in mutable_range", source_lines[0]).group(1) 
     peek = frame.f_locals[iterator_name] 
     if peek != x: 
      x = peek 
     else: 
      x += 1 

for i in mutable_range(10): 
    print(i) 
    if i == 3: 
     i = -10 
    if i == -8: 
     i = 6 

结果:

0 
1 
2 
3 
-10 
-9 
-8 
6 
7 
8 
9 

(免责声明:笔者是不负责使用的代码和傲慢的后续处罚由老鹰喂养你的肝脏所有永恒)

相关问题