简体   繁体   中英

Iterating sublists without using the list length

I have a list of things, and I need to apply some processing on successive (and overlapping) groups of 3 elements:

I can do it with:

for i in range(len(things)-2):
    process(things[i:i+3])

So for instance:

things=[0, 1, 2, 3, 4, 5, 6, 7]

And I want to process:

[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]

But is there a clever (but readable) way to do it without explicitly using len(things) ?

Yes, what you're looking for is called a sliding/moving window. There are different ways to achieve this but the easiest is to use tee() and islice() functions from itertools . Using this you can define a window() function like below with default window size of 2.

import itertools

def window(iterable, n=2):
    iters = itertools.tee(iterable, n)
    for i, it in enumerate(iters):
        next(itertools.islice(it, i, i), None)
    return zip(*iters)

Then you can use it as

>>> things=[0, 1, 2, 3, 4, 5, 6, 7]
>>> list(window(things, n = 3))
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7)]
>>> for elem in window(things, n = 3):
...     print(elem)
... 
(0, 1, 2)
(1, 2, 3)
(2, 3, 4)
(3, 4, 5)
(4, 5, 6)
(5, 6, 7)

Edit : For one time use a more simpler option may be

>>> list(zip(things, things[1:], things[2:]))
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7)]

Another way of doing it could be:

for i in things[0:-2]:
    a=things.index(i)
    process(things[a:a+3])

Let's try using enumerate , Here len(things[i : i+len_]) == len_ is to drop uneven sized list that get's accumulated at the end iterations.

len_ = 3

[things[i : i+len_] for i, j in enumerate(things) if len(things[i : i+len_]) == len_]

[[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]]

len_ = 4

[things[i : i+len_] for i, j in enumerate(things) if len(things[i : i+len_]) == len_]

[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM