Pythonic loops--how to get multiple elements while iterating a list
I want to iterate over my list and do something with multiple elements, not just one element. I want to take the first element and some elements after it (they could be sequential or maybe the 3rd element from the one returned).
l = ['a', 'b', 'c', 'd', 'e']
for items in l:
print items[:3]
The output should be:
['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']
There are a lot of good answers, what if want to skip elements? Say, get an element, skip the next element, and get the 3rd element?
Output:
('a', 'c'), ('b','d'), ('c', 'e')
I guess enumerate is the best way to handle this?
Iterating through lists so simple and elegant I hoped similar syntax would allow you to use it 开发者_开发问答inside a for loop on the element itself and not use range or enumerate.
l = ['a', 'b', 'c', 'd', 'e']
for items in l:
print (items[0], items[2])
(Yes, I know this code would give different results if the original list was a list containing lists. [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] would return [1, 3], [4, 6], [7, 9])
You can use zip and slicing:
l = range(5)
for grp in zip(*[l[i:] for i in range(3)]):
print grp
(0, 1, 2)
(1, 2, 3)
(2, 3, 4)
Edited to work properly, and with length of groups as one number. :)
What this does is call zip(l[0:], l[1:], l[2:])
, since * converts a list into separate arguments for function calls.
If you want the first and third element of subsequences, using zip is probably the simplest way:
l = range(10)
for grp in zip(l[0:], l[2:]):
print grp
(0, 2)
(1, 3)
(2, 4)
...
Or, use step if you want to jump further:
for grp in zip(l[0::3], l[2::3]):
print grp
(0, 2)
(3, 5)
(6, 8)
l = ['a', 'b', 'c', 'd', 'e']
subarraysize = 3
for i in range(len(l)-subarraysize+1):
print l[i:i+subarraysize]
Output:
['a', 'b', 'c']
['b', 'c', 'd']
['c', 'd', 'e']
Not very Pythonic I know, but in its favour it does actually work.
One refinement I might suggest would be modifying David Heffernan's suggestion to make it more pythonic, i.e.
l = ['a', 'b', 'c', 'd', 'e']
n = 3
m = [l[i:i+n] for i in range(len(l)-n+1)]
Output:
m = [['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
l = ['a', 'b', 'c', 'd', 'e']
>>> zip(l,l[1:],l[2:])
[('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e')]
>>> l = [chr(x+65) for x in xrange(26)]
>>> zip(l,l[1:],l[2:])
[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G'), ('F', 'G', 'H'), ('G', 'H', 'I'),
('H', 'I', 'J'), ('I', 'J', 'K'), ('J', 'K', 'L'), ('K', 'L', 'M'), ('L', 'M', 'N'), ('M', 'N', 'O'), ('N', 'O', 'P'),
('O', 'P', 'Q'), ('P', 'Q', 'R'), ('Q', 'R', 'S'), ('R', 'S', 'T'), ('S', 'T', 'U'), ('T', 'U', 'V'), ('U', 'V', 'W'),
('V', 'W', 'X'), ('W', 'X', 'Y'), ('X', 'Y', 'Z')]
Another version (similar to David's) is to use slicing in a generator expression:
size = 3
for grp in (l[i:i+size] for i in range(len(l)-size+1)):
print grp
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
This version yields lists instead of tuples, if that matters.
This is my solution to avoid the use of range
as required by OP in a comment.
>>> items = ['a', 'b', 'c', 'd', 'e']
>>> n = 3
>>> [item for item in map(lambda x: items[items.index(x):items.index(x) + n], it
ems) if len(item) == n]
[['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
精彩评论