I've written a bit of code like the following to compare items with other items further on in a list. Is there a more elegant pattern for this sort of dual iteration?
jump_item_iter = (j for j in items if some_cond)
try:
jump_item = jump_item_iter.next()
except StopIteration:
return
for item in items:
if jump_item is item:
try:
jump_item = jump_iter.next()
except StopIteration:
return
# do lots of stuff with item and jump_item
I don't think the "except StopIteration
" is very elegant
Edit:
To hopefully make it clearer, I want to visit each item in a list and pair it with the next item further on in the list (jump_item) which satisfies some_cond.
As far as I can see any of the existing solutions work on a general one shot, possiboly infinite iterator, all of them seem to require an iterable.
Heres a solution to that.
def batch_by(condition, seq):
it = iter(seq)
batch = [it.next()]
for jump_item in it:
if condition(jump_item):
for item in batch:
yield item, jump_item
batch = []
batch.append(jump_item)
This will easily work on infinite iterators:
from itertools import count, islice
is_prime = lambda n: n == 2 or all(n % div for div in xrange(2,n))
print list(islice(batch_by(is_prime, count()), 100))
This will print first 100 integers with the prime number that follows them.
I have no idea what compare()
is doing, but 80% of the time, you can do this with a trivial dictionary or pair of dictionaries. Jumping around in a list is a kind of linear search. Linear Search -- to the extent possible -- should always be replaced with either a direct reference (i.e., a dict) or a tree search (using the bisect module).
The following iterator is time and memory-efficient:
def jump_items(items):
number_to_be_returned = 0
for elmt in items:
if <condition(elmt)>:
for i in range(number_to_be_returned):
yield elmt
number_to_be_returned = 1
else:
number_to_be_returned += 1
for (item, jump_item) in zip(items, jump_items(items)):
# do lots of stuff
Note that you may actually want to set the first number_to_be_returned to 1...
Write a generator function:
def myIterator(someValue):
yield (someValue[0], someValue[1])
for element1, element2 in myIterator(array):
# do something with those elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With