Use the built-in function enumerate():
for idx, x in enumerate(xs):
print(idx, x)
It is non-Pythonic to manually index via for i in range(len(xs)): x = xs[i] or manually manage an additional state variable.
Check out PEP 279 for more.
Answer from Mike Hordecki on Stack OverflowWhy iterate over an array using the index?
python - loop through array or list in variable steps - Stack Overflow
Loop over an an array of array
Iterating through a numpy array
Videos
Use the built-in function enumerate():
for idx, x in enumerate(xs):
print(idx, x)
It is non-Pythonic to manually index via for i in range(len(xs)): x = xs[i] or manually manage an additional state variable.
Check out PEP 279 for more.
Using a for loop, how do I access the loop index, from 1 to 5 in this case?
Use enumerate to get the index with the element as you iterate:
for index, item in enumerate(items):
print(index, item)
And note that Python's indexes start at zero, so you would get 0 to 4 with the above. If you want the count, 1 to 5, do this:
count = 0 # in case items is empty and you need it after the loop
for count, item in enumerate(items, start=1):
print(count, item)
Unidiomatic control flow
What you are asking for is the Pythonic equivalent of the following, which is the algorithm most programmers of lower-level languages would use:
index = 0 # Python's indexing starts at zero for item in items: # Python's for loops are a "for each" loop print(index, item) index += 1
Or in languages that do not have a for-each loop:
index = 0 while index < len(items): print(index, items[index]) index += 1
or sometimes more commonly (but unidiomatically) found in Python:
for index in range(len(items)): print(index, items[index])
Use the Enumerate Function
Python's enumerate function reduces the visual clutter by hiding the accounting for the indexes, and encapsulating the iterable into another iterable (an enumerate object) that yields a two-item tuple of the index and the item that the original iterable would provide. That looks like this:
for index, item in enumerate(items, start=0): # default is zero
print(index, item)
This code sample is fairly well the canonical example of the difference between code that is idiomatic of Python and code that is not. Idiomatic code is sophisticated (but not complicated) Python, written in the way that it was intended to be used. Idiomatic code is expected by the designers of the language, which means that usually this code is not just more readable, but also more efficient.
Getting a count
Even if you don't need indexes as you go, but you need a count of the iterations (sometimes desirable) you can start with 1 and the final number will be your count.
count = 0 # in case items is empty
for count, item in enumerate(items, start=1): # default is zero
print(item)
print('there were {0} items printed'.format(count))
The count seems to be more what you intend to ask for (as opposed to index) when you said you wanted from 1 to 5.
Breaking it down - a step by step explanation
To break these examples down, say we have a list of items that we want to iterate over with an index:
items = ['a', 'b', 'c', 'd', 'e']
Now we pass this iterable to enumerate, creating an enumerate object:
enumerate_object = enumerate(items) # the enumerate object
We can pull the first item out of this iterable that we would get in a loop with the next function:
iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)
And we see we get a tuple of 0, the first index, and 'a', the first item:
(0, 'a')
we can use what is referred to as "sequence unpacking" to extract the elements from this two-tuple:
index, item = iteration
# 0, 'a' = (0, 'a') # essentially this.
and when we inspect index, we find it refers to the first index, 0, and item refers to the first item, 'a'.
>>> print(index)
0
>>> print(item)
a
Conclusion
- Python indexes start at zero
- To get these indexes from an iterable as you iterate over it, use the enumerate function
- Using enumerate in the idiomatic way (along with tuple unpacking) creates code that is more readable and maintainable:
So do this:
for index, item in enumerate(items, start=0): # Python indexes start at zero
print(index, item)
I'm probably missing something major here, but it seems like in most educational contexts online like Leetcode and courses and such, when the examples iterate over an array they do so like:
array = [1,2,3,4,5]
for i in range(len(array)):
print(array[i])rather than just iterating the thing:
for i in array:
print(i)I'm guessing it's to do with time complexity since indexing arrays is quick, but what's the problem with the latter approach?
Don't use a for loop.
for loops in python are different than in C or Java. In those languages, a for loop has an initial condition, a termination condition, and an increment for each time the loop runs. Whereas in python, a for loop is more of a for each loop - you give it an iterable object, and it runs the code for every item in that iterable object.
Modifying the iterable object while you're running through it is a bad idea that can have difficult-to-predict repercussions and will usually break your code.
However, you can always use a while loop:
a = [0,0,1,0,0,1,0]
idx = 0
while(idx < len(a) - 2):
print(idx)
if a[idx + 2] == 0:
idx += 2
elif a[idx + 2] == 1:
idx += 1
print(idx)
which produces the expected output
0 1 3 4 6
Or, if you change the increments to 3 and 2 respectively, rather than 2 and 1,
0 2 5
Your reasoning is pretty confusing, and I don't see ANY application for this, but here is how I understand your problem...
The reason is because you aren't actually returning the values, you're simply returning the index + 3, which is wrong to begin with. What you're trying to do is point to a new index of the array based on its value and return the index if it contains a value greater than 0.
You need to reference the index you want, check its value, then return the index which contains a value.
a = [0, 0, 1, 0, 0, 1, 0]
for i, v in enumerate(a):
if i == 0:
print(i)
next
if v == 0:
next
else
print(i)
But let's be honest, this is extremely ugly and un-pythonic. Let's simply check for whether a[i] contains a value, and if so, return the index...
for i, v in enumerate(a):
if v or i == 0:
print(i)
The purpose of if v or i == 0 is to check if v has a value, if so, print the index. OR if we are looking at the first element of i.
If you want to EXPLICITLY move the index by two, you must set your index at the start and use a while loop, since enumerate can't help you here and doesn't actually let you move the indicies...
a = [0, 0, 1, 0, 0, 1, 0]
i = 0
while i < len(a) - 1: # -1 to avoid out of bounds error
print(i)
if a[i + 2] == 0:
i += 2
elif a[i + 2] == 1:
i += 1
print(i) # Final print statement for the last index at the end of the while loop
I want to impress upon you the fact that this solution does NOT scale with different or larger lists, which is why it isn't recommended. By simply checking for whether a value does or doesn't exist, you guarantee your accuracy.
You should simply return the index based upon whether or not it contains a value. Even for very large lists, this will be extremely fast, and will always scale, even for values greater than 1.
The only other reason I would see you would want to do this differently is if you're doing string-search algorithms.