Home > Mobile >  Can range(len()) be evaluated multiple times within a for loop?
Can range(len()) be evaluated multiple times within a for loop?

Time:04-17

Within a while-loop the condition get's iteratively re-evaluated. Example:

while i < len(nums):

Both the latest index i and the latest length of nums are used to re-evaluate the condition.

This is not the case within a for-loop. Example:

for i in range(len(nums)):

Here range(len(nums)) is created and remains unchanged even when the length of nums changes (e.g., due to popping values within the loop). Is my understanding of this process correct? Is there a way to make the for-loop dependent on 'a moving goal post' (the changing nums length)?

CodePudding user response:

This is not the case within a for-loop

No. This is the case when you create a range object. range does not store a reference to nums it just takes the integer. If you had a list

ls = [0, 1, 2, 3]

Then you could write:

for i in ls:
    ls.append(i)

and the loop would run forever, because you are getting i from ls and ls is being added to each time. I would not recommend trying to use this to achieve your goal, though. Using a while loop makes sense here.

CodePudding user response:

You could use enumerate(nums) to iterate through the list getting the current index and still go further if the list gets longer.

In the following example i used random to have a chance of applying a new item with every iteration.

>>> import random
>>>
>>> nums = ["a", "a"]
>>>
>>> for i, val in enumerate(nums):
...    if random.randint(0, 1)==0:
...       nums.append("b")
...    print(str(i) ":" val)
...
0:a
1:a
2:b
3:b

CodePudding user response:

you can use a variable and set the length of the array for each loop

 nums = [1, 2 ,3 ,4]
 i=0
 array_length=len(nums)
 while i < array_length:
   nums.pop()
   print(nums)
   array_length=len(nums)

CodePudding user response:

You could make a generator that simply hides a while loop.

def range_len(lst):
    i = 0
    while i < len(lst):
        yield i
        i  = 1

for i in range_len(nums):
    ...

This is pointless except to demonstrate that a for loop can iterate over a changing iterable. It works because the lst within the generator is the same object as nums and so its length will be re-evaluated on each iteration.

CodePudding user response:

If there is a necessary reason to use for and not while then here are some ideas:

If the intent is to avoid running out of list boundaries as a result of the list shrinking at runtime (I have not tested this), then I would put a condition at that critical part of the body to reassess i against len(n) and break accordingly.

If the intent is to continue with the for loop in case the length expands, then maybe I would consider nested loops with the outer being while True with a breaking condition (if i reaches len(n)). In that case the starting value of the inner loop will not always be zero.

  • Related