有没有办法影响Python中的范围计数器?

时间:2017-06-19 18:23:59

标签: java python

我正在尝试运行一个带有for循环的python程序,每次从1到我的列表长度变量i增加1。在java中,我想要的代码看起来像这样:

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循环和计数器来模拟这个?

6 个答案:

答案 0 :(得分:4)

你需要一个while循环:

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

答案 1 :(得分: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

(免责声明:作者不负责使用代码以及随后用老鹰喂养肝脏的狂妄自负惩罚

答案 2 :(得分:1)

您无法修改步数mid计数,但如果单步执行是常量,则可以在开头指定它:

# 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]

如果你的情况很遗憾,不是整个迭代过程中步长不变的情况,你肯定需要一个正确的循环,正如你猜测的那样。

答案 3 :(得分:1)

在python中它与Java非常相似。您可以根据以下不同条件动态增加计数器:

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

答案 4 :(得分:1)

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

要通过多个步骤执行此操作,itertools收件人定义了consume函数:

var model = null;
function onNavigatingTo(args) {
	page = args.object;
	model = new Observable();
  
  model.set('amount', 100);
  model.set('maxAmount', 500);
  model.set('minAmount', 0);

	page.bindingContext = model;
}

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

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.

这些是高效的,因为它们使用内置类型和功能。

答案 5 :(得分: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 head的顶部;调试留给任何恼怒的人,而循环足够走路。我认为它更能说明了幕后发生的事情。

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

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