You can simply use slicing:
for item in I[1:]:
print(item)
And if you want indexing, use pythonic-style enumerate:
START = 1
for index, item in enumerate(I[START:], START):
print(item, index)
Answer from Mastermind on Stack OverflowYou can simply use slicing:
for item in I[1:]:
print(item)
And if you want indexing, use pythonic-style enumerate:
START = 1
for index, item in enumerate(I[START:], START):
print(item, index)
First thing is to remember that python uses zero indexing.
You can iterate throught the list except using the range function to get the indexes of the items you want or slices to get the elements.
What I think is becoming confusing here is that in your example, the values and the indexes are the same so to clarify I'll use this list as example:
I = ['a', 'b', 'c', 'd', 'e']
nI = len(I) # 5
The range function will allow you to iterate through the indexes:
for i in range(1, nI):
print(i)
# Prints:
# 1
# 2
# 3
# 4
If you want to access the values using the range function you should do it like this:
for index in range(1, nI):
i = I[index]
print(i)
# Prints:
# b
# c
# d
# e
You can also use array slicing to do that and you don't even need nI. Array slicing returns a new array with your slice.
The slice is done with the_list_reference[start:end:steps] where all three parameters are optional and:
start is the index of the first to be included in the slice
end is the index of the first element to be excluded from the slice
steps is how many steps for each next index starting from (as expected) the start (if steps is 2 and start with 1 it gets every odd index).
Example:
for i in I[1:]:
print(i)
# Prints:
# b
# c
# d
# e
There is actually no need to use indices here, as Python loops allow to iterate over elements directly. Then, with simple list slicing you can take the range you want:
integers = [1,3,2,4]
for integer in integers[1:]:
print(integer)
Or, to iterate over elements instead of indexes, but avoid creating a new copy of the list (slices create a new list object), you can use islice:
from itertools import islice
for integer in islice(integers, 1, None):
print(integer)
The range() function
We can generate a sequence of numbers using range() function. range(10) will generate numbers from 0 to 9 (10 numbers). We can also define the start, stop and step size as
range(start,stop,step size). step size defaults to 1 if not provided. This function does not store all the values in memory, it would be inefficient. So it remembers the start, stop, step size and generates the next number on the go.
Your code should looks like:
integer = [1,3,2,4]
for i in range(1,len(integer)):
print (integer[i])
Output:
3
2
4
python - Iterating over every two elements in a list - Stack Overflow
Start iteration from second element in Python - Stack Overflow
python - Iterate every 2 elements from list at a time - Stack Overflow
pandas - iterate on python list (a list from second item from another list) - Stack Overflow
edit: forgot to mention I want the indeces not just the items
the methods I can think of are:
for i in range(len(arr) - 1)
for i, e in enumerate(arr[:len(arr) - 1])
I know range(len(arr)) is frowned upon, but I don't see how it's worse than enumerate in this case. In fact using enumerate on a shortened list and calling len to find the second to last element of that list seems extremely clunky and far less readable.
What's the best practice for doing this?
Starting with Python 3.12, you can use the batched() function provided by the itertools module:
from itertools import batched
for x, y in batched(l, n=2):
print("%d + %d = %d" % (x, y, x + y))
Otherwise, you need a pairwise() (or grouped()) implementation.
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return zip(a, a)
for x, y in pairwise(l):
print("%d + %d = %d" % (x, y, x + y))
Or, more generally:
def grouped(iterable, n):
"s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
return zip(*[iter(iterable)]*n)
for x, y in grouped(l, 2):
print("%d + %d = %d" % (x, y, x + y))
In Python 2, you should import izip as a replacement for Python 3's built-in zip() function.
All credit to martineau for his answer to my question, I have found this to be very efficient as it only iterates once over the list and does not create any unnecessary lists in the process.
N.B: This should not be confused with the pairwise recipe in Python's own itertools documentation, which yields s -> (s0, s1), (s1, s2), (s2, s3), ..., as pointed out by @lazyr in the comments.
Little addition for those who would like to do type checking with mypy on Python 3:
from typing import Iterable, Tuple, TypeVar
T = TypeVar("T")
def grouped(iterable: Iterable[T], n=2) -> Iterable[Tuple[T, ...]]:
"""s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), ..."""
return zip(*[iter(iterable)] * n)
Well you need tuple of 2 elements, so
data = [1,2,3,4,5,6]
for i,k in zip(data[0::2], data[1::2]):
print str(i), '+', str(k), '=', str(i+k)
Where:
data[0::2]means create subset collection of elements that(index % 2 == 0)zip(x,y)creates a tuple collection from x and y collections same index elements.
Use itertools.islice() to slice skipping the first.
from itertools import islice
for (script, location) in islice(self.device.scripts, 1, None):
pass # do stuff
Just slice it.
for script, location in self.device.scripts[1:]:
pass
For your second question, you don't need to worry about any IndexError since slicing returns an empty list when it's out of range.
You can use iter:
>>> seq = [1,2,3,4,5,6,7,8,9,10]
>>> it = iter(seq)
>>> for x in it:
... print (x, next(it))
...
[1, 2]
[3, 4]
[5, 6]
[7, 8]
[9, 10]
You can also use the grouper recipe from itertools:
>>> from itertools import izip_longest
>>> def grouper(iterable, n, fillvalue=None):
... "Collect data into fixed-length chunks or blocks"
... # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
... args = [iter(iterable)] * n
... return izip_longest(fillvalue=fillvalue, *args)
...
>>> for x, y in grouper(seq, 2):
... print (x, y)
...
[1, 2]
[3, 4]
[5, 6]
[7, 8]
[9, 10]
You could do it your way, just add a step part to the slice to make both slices skip a number:
for v, w in zip(l[::2],l[1::2]): # No need to end at -1 because that's the default
print [v, w]
But I like helper generators:
def pairwise(iterable):
i = iter(iterable)
while True:
yield i.next(), i.next()
for v, w in pairwise(l):
print v, w
Try list comprehension :
list1 = [['id_5', 4], ['id_6', 4], ['id_7', 4], ['id_0', 12], ['id_1', 4], ['id_2', 8], ['id_3', 8], ['id_4', 4], ['id_8', 1]]
list2 = [['id_5', 5], ['id_6', 5], ['id_7', 5], ['id_0', 15], ['id_1', 5], ['id_2', 10], ['id_3', 10], ['id_4', 5]]
list1_out = [i[1] for i in list1]
list2_out = [i[1] for i in list2]
Output :
[4, 4, 4, 12, 4, 8, 8, 4, 1] # list1_out
[5, 5, 5, 15, 5, 10, 10, 5] # list2_out
There are different approaches, a simple comprehension would do:
[x[1] for x in l]
Also with map and operator.itemgetter:
from operator import itemgetter
list(map(itemgetter(1), l))
For printing the results you can call print with unpacking:
print(*out_list)
For example:
>>> l = [['id_5', 4], ['id_6', 4], ['id_7', 4], ['id_0', 12], ['id_1', 4], ['id_2', 8], ['id_3', 8], ['id_4', 4], ['id_8
', 1]]
>>> from operator import itemgetter
>>> out_list = list(map(itemgetter(1), l))
>>> out_list
[4, 4, 4, 12, 4, 8, 8, 4, 1]
>>> print(*out_list)
4 4 4 12 4 8 8 4 1
All as a one liner:
>>> print(*(x[1] for x in l))
4 4 4 12 4 8 8 4 1
listOfStuff =([a,b], [c,d], [e,f], [f,g])
for item in listOfStuff[1:3]:
print item
You have to iterate over a slice of your tuple. The 1 is the first element you need and 3 (actually 2+1) is the first element you don't need.
Elements in a list are numerated from 0:
listOfStuff =([a,b], [c,d], [e,f], [f,g])
0 1 2 3
[1:3] takes elements 1 and 2.
A more memory efficient way to iterate over a slice of a list would be to use islice() from the itertools module:
from itertools import islice
listOfStuff = (['a','b'], ['c','d'], ['e','f'], ['g','h'])
for item in islice(listOfStuff, 1, 3):
print(item)
# ['c', 'd']
# ['e', 'f']
However, this can be relatively inefficient in terms of performance if the start value of the range is a large value since islice would have to iterate over the first start value-1 items before returning items.