开发者

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']]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜