Frontier
Frontier

Reputation: 149

Finding an index in range of values between 0-100 in Python

This is a two part question, I have to make a selection of 2 indexes via a random range of any number of integers in a list. Can't return both if they're both in the same range as well

Selection1 = random.randint(0,100)
Selection2 = random.randint(0,100)

For the sake of this argument, say:

Selection1 = 10
Selection2 = 17
And the list would be like so [25, 50, 75, 100]

Both would return the index of 0 because they fall between 0-25

So both would fall into the first index range, the problem is i'm having some issues trying to fit it into this range (IE: 0-25) which will return this first index (return list[0])

What is the syntax for this type of logic in python?

I'm sure I can figure out how to return different indexes if they fall in the same range, probably just loop reset to the loop but if I can get some advice on that it wouldn't hurt.

I'll give the code i'm working with right now as a guideline. Mostly at the bottom is where i'm struggling.

Code Here

def roulette_selection(decimal_list, chromosome_fitness, population):
    percentages = []
    for i in range(population):
        result = decimal_list[i]/chromosome_fitness
        result = result * 100
        percentages.append(result)

    print(percentages)
    range_in_fitness = []
    current_percent = 0

    for i in range(population):
        current_percent = percentages[i] + current_percent
        range_in_fitness.append(current_percent)
    parent1 = random.randint(0, 100)
    parent2 = random.randint(0, 100)

    for i in range(population):
        if parent1 >= range_in_fitness[i] and parent1<=range_in_fitness[i+1]:


    print(parent1, parent2)
    print(range_in_fitness)

Upvotes: 2

Views: 4070

Answers (2)

aruisdante
aruisdante

Reputation: 9095

If your list of ranges is sorted, or it is acceptable to sort it, and is contiguous (no gaps), you can use Python's bisect module to do this in an efficient manner. Example:

>>> l = [25, 50, 75, 100]
>>> import bisect
>>> bisect.bisect(l, 10)
0
>>> bisect.bisect(l, 17)
0
>>> bisect.bisect(l, 55)
2
>>> bisect.bisect(l, 25)
1

Bisect returns the index of where the input number should fall into the list to maintain sort order. Note that this is a little confusing to think about at first; In the case of 55 above, it returns 2 because it should be inserted at index 2 as it falls between the current values at indices 1 and 2. If you give it a number exactly on a range boundary, it will 'fall to the right', as evidenced by the bisect(l,25) example.

The linked documentation includes a set of recipes for searching through sorted lists using bisect.

Upvotes: 4

jedwards
jedwards

Reputation: 30230

Given an input val and a list of range delimiters delims, here are two approaches:

# Both methods require range_delims to be sorted
range_delims = [25,50,75,100]

# Simple way
def find_range1(val, delims):
    for i,d in enumerate(delims):
        if val < d: return i

print find_range1(10,  range_delims)  # 0
print find_range1(17,  range_delims)  # 0
print find_range1(32,  range_delims)  # 1
print find_range1(64,  range_delims)  # 2
print find_range1(96,  range_delims)  # 3
print find_range1(101, range_delims)  # None


# More explicit, possibly unnecessarily so
import math

def find_range2(val, delims):
    lbl = [float('-inf')] + delims
    ubl = delims + [float('inf')]
    for (i,(lb,ub)) in enumerate(zip(lbl, ubl)):
        if lb <= val < ub: return i

print find_range2(10,  range_delims)  # 0
print find_range2(17,  range_delims)  # 0
print find_range2(32,  range_delims)  # 1
print find_range2(64,  range_delims)  # 2
print find_range2(96,  range_delims)  # 3
print find_range2(101, range_delims)  # 4

The first just compares val to the elements of delims and when it finds that val is less than the element, returns the index of that element.

The second is a little more verbose, generating both upper and lower bounds, and ensuring that val is between them. For interior elements of delims the bounds are list elements, for the 2 exterior elements of delims, the bounds are the element and either + or - infinity.

Note: Both approaches require the input list of delimiters to be sorted. There are ways to deal with different delimiter list formats, but it looks like you have a sorted list of delimiters (or could sort it without issue).

Upvotes: 1

Related Questions