Home > Back-end >  Error: Too many values unpack (expected 2) when trying to loop
Error: Too many values unpack (expected 2) when trying to loop

Time:11-14

I'm trying to find a pair that is equal to 10 but cannot find it.

listOfIntegers = [8, 7, 2, 5, 3, 1]
target = 10
noOfpairs = 0
def findPair(listOfIntegers, target):
    for i,j in range (len(listOfIntegers)),(len(listOfIntegers)):
        if listOfIntegers[i]   listOfIntegers[j 1] == target:
            print(listOfIntegers[i], "and", listOfIntegers[j], "is a pair")
            noOfpairs  = 1
            print("number of pairs : ",noOfpairs)
            break
        
print(findPair(listOfIntegers, target))

CodePudding user response:

I don't know what your expected behaviour is, based on the way your code is written I assume you want to find the first pair and break...? But then why are you printing "number of pairs" if you break at the first pair...?

I'm going to assume you want to find the total number of consecutive pairs in a list that add to 10.

Your code, and where it's wrong:

  1. noOfpairs is defined outside function findPair, but used inside.
  2. Your for loop brackets are wrong - this is where you are getting your error.
  3. You're breaking after finding the first pair (which might be what you want but it doesn't look like it)
  4. You're running print("number of pairs : ", noOfpairs) inside the for loop (it's not a syntactical error but an inaccuracy - again, I don't get your expected behaviour)
  5. You're printing the function (print(findPair(listOfIntegers, target))) as if it returned a value - it does not have a return statement therefore returns None. Run the function like this: findPair(listOfIntegers, target) or make it return noOfpairs.
  6. In your for loop, why do you have 2 values i and j that both represent the exact same value for every iteration? It's not syntactically wrong but it makes no sense.

Correct code:

listOfIntegers = [8, 2, 5, 5, 1]
value_wanted = 10


def findPair(int_list, target):
    noOfpairs = 0
    for i in range(len(int_list) - 1):    # To stop index out of bounds error
        if int_list[i]   int_list[i   1] == target:
            print(int_list[i], "and", int_list[i   1], "is a pair")
            noOfpairs  = 1
    print("number of pairs : ", noOfpairs)


findPair(listOfIntegers, value_wanted)

I hope this helped you - if this is not what you wanted to happen, please include what you want your code to return in your question.

CodePudding user response:

Edit 2

Okay thank you for the insight from the comments; If the case is the only find how many pairs equal 10, you can use the itertools.permutations:

from itertools import permutations

target = 10
items = [8, 7, 2, 5, 3, 1]

test_func = lambda pair:sum(pair) == target
count = sum(map(test_func, permutations(items, 2)))
assert count == 4

There are many ways you can write this, I opted for something that looked clean. Fundmentally it's three steps:

  1. Build a set of pairs
  2. test each against your target 10
  3. sum the booleans, each resulting in 1 or 0

Original Answer:

It seems like a bracket misplacement:

>>> listOfIntegers = [8, 7, 2, 5, 3, 1]
>>> range (len(listOfIntegers)),(len(listOfIntegers))
(range(0, 6), 6)

But you want to produce one range:

>>> range (len(listOfIntegers),(len(listOfIntegers)))
range(6, 6)

Edit:

Interestingly I got downvoted; To clarify, the question is "Error: Too many values unpack (expected 2) when trying to loop", thus the correction to fix the bug is exactly a bracket issue:

listOfIntegers = [8, 7, 2, 5, 3, 1]
target = 10
noOfpairs = 0
def findPair(listOfIntegers, target):
             # range (len(listOfIntegers)),(len(listOfIntegers))
    for i,j in range (len(listOfIntegers),(len(listOfIntegers))):
        if listOfIntegers[i]   listOfIntegers[j 1] == target:
            print(listOfIntegers[i], "and", listOfIntegers[j], "is a pair")
            noOfpairs  = 1
            print("number of pairs : ",noOfpairs)
            break


print(findPair(listOfIntegers, target))

CodePudding user response:

Passing two arguments to range does not return a list of pairs - the first argument in that case is interpreted as the number to start the range from. Example:

print(list(range(3)))
print(list(range(1, 3)))

Output:

[0, 1, 2]
[1, 2]

For this task, a while loop is the simplest solution:

listOfIntegers = [8, 7, 2, 5, 3, 1]
target = 10
noOfpairs = 0
def findPair(iterable, pairSum):
    i = 0
    while i < len(iterable):
        j = i   1
        if listOfIntegers[i]   listOfIntegers[j] == target:
            print(listOfIntegers[i], "and", listOfIntegers[j], "is a pair")
            noOfpairs  = 1
            print("number of pairs:", noOfpairs)
            break
        
findPair(listOfIntegers, target)

Note how I changed the name of the arguments of the function - they should never be the same as the names of the variables passed to them, to avoid possible unexpected behaviour.

  • Related