Home > Software design >  Index value not in list
Index value not in list

Time:10-27

I need to write code that returns 2 index numbers of an array. The function takes 2 arguments, one is an array and the other is an integer.

I need to check if two of the values inside the array adds up to the integer and using the numbers inside the array only once.

Here is my code:

def func(a,b):
    for i in a: 
        cnt = 0
        while cnt < len(a):
            if i   a[cnt] == b and i != a[cnt]:
                return list([i,a[cnt]])
            else:
                cnt  = 1
print(func([3,7,2,10,20],27))

My output for func([3, 7, 2, 10, 20], 27) is [7, 20].

This code shows that the loop can find the numbers which add up to the integer.

But when I do this:

def func(a,b):
    for i in a: 
        cnt = 0
        while cnt < len(a):
            if i   a[cnt] == b and i != a[cnt]:
                return a.index(i,a[cnt])
            else:
                cnt  = 1               
print(func([3,7,2,10,20],27))

I get the Value error: 7 not in list, which clearly is.

I've had this issue working with other exercises as well.

Am I doing something wrong or the index function isn't suppose to be used like that.

What would be an efficient way to return the index numbers without having to write another loop for it?

CodePudding user response:

The second parameter to index that you're passing is actually the starting index on the list in which the search for the element will start (as you can see here). If you remove it, you'll see that it returns the first value you want (but not the second). It is relevant to note that the index method will only ever return the first occurrence of the value.

def func(a,b):
    for i in a: 
        cnt = 0
        while cnt < len(a):
            if i   a[cnt] == b and i != a[cnt]:
                return a.index(i)
            else:
                cnt  = 1               
print(func([3,7,2,10,20],27))
>>> 1

This happens because the value you're passing as the starting index (a[cnt]) is greater than the actual index of the number (1).

By removing it, you search through all the list, and find the correct value (remembering that Python uses zero-indexed iterators).

But since you want to return a list with both values, you need to explicitly state you want the index for each, such as:

def func(a,b):
    for i in a: 
        cnt = 0
        while cnt < len(a):
            if i   a[cnt] == b and i != a[cnt]:
                return [a.index(i), a.index(a[cnt])]
            else:
                cnt  = 1
print(func([3,7,2,10,20],27))
>>> [1, 4]

You could achieve the same results using two for loops, however, in a cleaner way (also gave meaningful names to variables):

def find_indices_for_sum(array, sum_value):
    for i in array:
        for j in array:
            if i   j == sum_value and i != j:
                return [array.index(i), array.index(j)]
print(find_indices_for_sum([3,7,2,10,20],27))
>>> [1, 4]

If you want to be able to deal with equal numbers, you can change the comparison strategy altogether, using indices instead of values, since the former are unique in a list, but the latter are not. enumerate is a good option here, since it allows to iterate both through index and values at the same time in a clean way.

def find_indices_for_sum(array, sum_value):
    for i, value_i in enumerate(array):
        for j, value_j in enumerate(array):
            if i != j and value_i   value_j == sum_value:
                return [i, j]
print(find_indices_for_sum([3,3],6))
>>> [0, 1]
  • Related