How to create a variable range?

I need to find an item in the list around a given index with a given radius. I am currently using this function to generate alternating offsets for a search:

def generateSearchIndizes(radius):
    for i in range(1, radius + 1):
        yield i
        yield -i

The code that performs the search looks something like this:

for i in generateSearchIndizes():
    if pred(myList[baseIndex + i]):
        result = myList[baseIndex + i]
        break # terminate search when first item is found

My question is: is there a more elegant way to generate search indexes, perhaps without defining a special function?

+5
source share
7 answers

there is a more elegant way to generate search indexes

I don’t think there is a more elegant way. Your code is very simple and straightforward.

perhaps without defining a special function?

Yes, it is definitely possible.

>>> [b for a in ((x,-x) for x in range(1, 10 + 1)) for b in a]
[1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]
+4
source

Here is my move:

from itertools import chain

>>> list(chain(*zip(range(1, 7), range(-7, 0)[::-1])))
[1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6]

Adjust as needed. :)

+2

, ?

for i in (x/2 * (x%2 * 2 - 1) for x in xrange(2, radius*2)):
    print i

" "...

, , - .:)

0

, funky:

found = False
for i_abs in range(1, radius+1):
    for i in (i_abs, -i_abs):
        listitem = myList[baseIndex + i]
        if pred(listitem):
             result = listitem
             found = True
             break # terminate search when first item is found 
    if found:
        break
else:
    # handling in case no match found for pred

:

  • 0-

  • , i_abs

  • , ; myList[baseIndex+i] listitem

  • , ( found ), result ,

:

for i_abs in range(1, radius+1):
    for i in (i_abs, -i_abs):
        listitem = myList[baseIndex + i]
        if pred(listitem):
             return listitem

found.

0

alternate -i, i? :

for i in range(-radius, radius+1):
    listitem = myList[baseIndex + i]
        if pred(listitem):
            return listitem  

, , , :

for i in sorted(range(-radius, radius+1), key=abs):
    listitem = myList[baseIndex + i]
        if pred(listitem):
            return listitem  

, sorted(range(-radius,radius+1),key=abs) .

0- , if not i: continue .

0

, - , , :

radius = 3
for outerbounds in ((-r,r) for r in range(1,radius+1)):
    for i in outerbounds :
        print i
# -1
# 1
# -2
# 2
# -3
# 3
0

, yield 0 , (-).

:

def gen_offsets():
    offset= 0
    yield offset
    step= 1; sign= 1
    while 1:
        offset+= sign*step
        yield offset
        step+= 1; sign= -sign

A more bizarre (aka non-pythonic) way to write the above algorithm:

import itertools as it, operator as op

def gen_offsets():
    steps= it.imap(op.mul, it.count(1), it.cycle( (1, -1) ))
    offset= 0
    yield offset
    for step in steps:
        offset+= step
        yield offset
0
source

All Articles