Earlier quoted context omitted.
Sure, there are many ways to do it, but I think the author was going for speed here.
Did you test and time the itertools version?
EDIT: See update above.
21–30 of 114 posts
i = iter(array) return zip(i, i, i) There you go. All but neceessary magic gone with just one line more.
Earlier quoted context omitted.
I'd be surprised if my way is slower. Any time you unpack into a function such as zip() python has to create an intermediary list to store all the results before calling the function.
You could always use izip: http://docs.python.org/2/library/itertools.html#itertools.iz...
It does not rely on an implementation detail, that is how iterators work. He's just supplied the same iterator to a function which consumes iterators... that's exactly the expected behaviour.
The fact that zip evaluates its arguments in order is an implementation detail. It could evaluate them in reverse order, in which case this code would not behave as expected.
i = iter(array) return zip(i, i, i) There you go. All but neceessary magic gone with just one line more.
zip(arr[::3], arr[1::3], arr[2::3])
which is nearly as fast but doesn't work with iterators.
If you want to use iterators you could also do zip(islice(arr, 0, None, 3), islice(arr, 1, None, 3), islice(arr, 2, None, 3))
which is a tad slower.We all love short and fast. But this is definitely an interesting approach. I'd love to see similar approaches to problems if you guys can point out to some.
>>> some_boolean = False
>>> ["Thing 1", "Thing 2"][some_boolean]
"Thing 1"It's not brilliant. This accomplishes the same thing without being hard to understand: from itertools import islice iterator = iter(array) try: while True: yield list(islice(iterator, 3)) except StopIteration: pass
Turns out that islice doesn't raise an IterationError, it just returns an empty list.
Fixing the problems, it runs in 237 μsec per loop, around 23 times more than the zip version.
Earlier quoted context omitted.
I'd be surprised if my way is slower. Any time you unpack into a function such as zip() python has to create an intermediary list to store all the results before calling the function.
You could always use izip: http://docs.python.org/2/library/itertools.html#itertools.iz...
It's not brilliant. This accomplishes the same thing without being hard to understand: from itertools import islice iterator = iter(array) try: while True: yield list(islice(iterator, 3)) except StopIteration: pass
This crashed my computer (it's an infinite loop that needs too much memory, apparently), and there's a mistake (the i is not defined). Turns out that islice doesn't raise an IterationError, it just returns an empty list. Fixing the problems, it runs in 237 μsec per loop, around 23 times more than the zip version.
while True:
result = list(islice(iterator, 3))
if not result:
break
yield result