简体   繁体   English

如何在 Python 的循环中更改 for-loop 迭代器变量?

[英]How to change for-loop iterator variable in the loop in Python?

I want to know if is it possible to change the value of the iterator in its for-loop?我想知道是否可以在其 for 循环中更改迭代器的值?

For example I want to write a program to calculate prime factor of a number in the below way :例如,我想编写一个程序来计算一个数的素数,方法如下:

def primeFactors(number):
    for i in range(2,number+1):
        if (number%i==0)
            print(i,end=',')
            number=number/i 
            i=i-1 #to check that factor again!

My question : Is it possible to change the last two line in a way that when I change i and number in the if block, their value change in the for loop!我的问题:是否可以更改最后两行,当我在if块中更改inumber时,它们的值会在for循环中更改!

Update: Defining the iterator as a global variable, could help me?更新:将迭代器定义为global变量,对我有帮助吗? Why?为什么?

No.不。

Python's for loop is like other languages' foreach loops. Python 的for循环类似于其他语言的foreach循环。 Your i variable is not a counter, it is the value of each element in a list, in this case the list of numbers between 2 and number+1.您的i变量不是计数器,它是列表中每个元素的值,在本例中是 2 和 number+1 之间的数字列表。 Even if you changed the value, that would not change what was the next element in that list.即使您更改了值,也不会更改该列表中的下一个元素。

Short answer (like Daniel Roseman's): No简短的回答(如丹尼尔罗斯曼的):不

Long answer: No, but this does what you want:长答案:不,但这可以满足您的要求:

def redo_range(start, end):
    while start < end:
        start += 1
        redo = (yield start)
        if redo:
            start -= 2

redone_5 = False
r = redo_range(2, 10)
for i in r:
    print(i)
    if i == 5 and not redone_5:
        r.send(True)
        redone_5 = True

Output:输出:

3
4
5
5
6
7
8
9
10

As you can see, 5 gets repeated.如您所见, 5被重复。 It used a generator function which allows the last value of the index variable to be repeated.它使用了一个生成器函数,该函数允许重复索引变量的最后一个值。 There are simpler methods ( while loops, list of values to check, etc.) but this one matches you code the closest.有更简单的方法( while循环、要检查的值列表等),但这个方法与您的代码最接近。

The standard way of dealing with this is to completely exhaust the divisions by i in the body of the for loop itself:处理这个问题的标准方法是在for循环本身的主体中完全用尽i的除法:

def primeFactors(number):
    for i in range(2,number+1):
        while number % i == 0:
            print(i, end=',')
            number /= i

It's slightly more efficient to do the division and remainder in one step:一步完成除法和余数的效率略高:

def primeFactors(number):
    for i in range(2, number+1):
        while True:
            q, r = divmod(number, i)
            if r != 0:
                break
            print(i, end=',')
            number = q

The only way to change the next value yielded is to somehow tell the iterable what the next value to yield should be .改变下一个产生的值的唯一方法是以某种方式告诉可迭代的下一个产生的值应该是什么。 With a lot of standard iterables, this isn't possible .有很多标准的迭代,这是不可能的 however, you can do it with a specially coded generator:但是,您可以使用特殊编码的生成器来完成:

def crazy_iter(iterable):
  iterable = iter(iterable)
  for item in iterable:
    sent = yield item
    if sent is not None:
      yield None  # Return value of `iterable.send(...)`
      yield sent

num = 10
iterable = crazy_iter(range(2, 11))
for i in iterable:
  if not num%i:
    print i
    num /= i
    if i > 2:
      iterable.send(i-1)

I would definitely not argue that this is easier to read than the equivalent while loop, but it does demonstrate sending stuff to a generator which may gain your team points at your next local programming trivia night.我绝对不会争辩说这比等效的while循环更容易阅读,但它确实演示了将内容发送到生成器,这可能会在您的下一个本地编程琐事之夜获得您的团队积分。

It is not possible the way you are doing it.你这样做是不可能的。 The for loop variable can be changed inside each loop iteration, like this: for 循环变量可以每次循环迭代中更改,如下所示:

for a in range (1, 6):
    print a
    a = a + 1
    print a
    print

The resulting output is:结果输出是:

1
2

2
3

3
4

4
5

5
6

It does get modified inside each for loop iteration.确实在每个for 循环迭代中进行了修改。

The reason for the behavior displayed by Python's for loop is that, at the beginning of each iteration, the for loop variable is assinged the next unused value from the specified iterator . Python 的for 循环显示的行为的原因是,在每次迭代开始时, for 循环变量指定的迭代器中分配下一个未使用的值。 Therefore, whatever changes you make to the for loop variable get effectively destroyed at the beginning of each iteration.因此,您对for 循环变量所做的任何更改都会在每次迭代开始时被有效地破坏。

To achieve what I think you may be needing, you should probably use a while loop , providing your own counter variable, your own increment code and any special case modifications for it you may need inside your loop.为了实现我认为您可能需要的内容,您可能应该使用while 循环,提供您自己的计数器变量、您自己的增量代码以及您在循环中可能需要的任何特殊情况修改。 Example:例子:

a = 1
while a <= 5:
    print a
    if a == 3:
        a = a + 1
    a = a + 1
    print a
    print

The resulting output is:结果输出是:

1
2

2
3

3
5

5
6

Yes, we can only if we dont change the reference of the object that we are using.是的,只有当我们不改变我们正在使用的对象的引用时,我们才能做到这一点。 If we can edit the number by accessing the reference of number variable, then what you asked is possible.如果我们可以通过访问数字变量的引用来编辑数字,那么您所问的就是可能的。

A simple example:一个简单的例子:

a=[1,2,3]
a=a+[4]==>here, a new object is created which plots to different address.
a+=[4]==>here , the same object is getting updated which give us the desired result.



number=10
list1=list(range(2,number+1))
# list1   
for i in list1:
    print(list1,i)
    if (number%i==0):
        print(i,end=',')
        number=number//i #we can simply replace it with number//=i to edit the number without changing the reference or without creating a new object.
        try:
            [list1.pop() for i in range(10,0,-1) if(i>number)]
             #here pop() method is working on the same object which list created by number refers. so, we can able to change the iterable in the forloop. 

        except:
            continue
        i=i-1 #to check that factor again!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM