"TypeError: cannot unpack non-iterable int object" with filter function

Question:

I have a list and I want to filter the tuples in this list using the filter function, but I’m running into a problem that I can’t solve.

My code:

liste = [(3,4,5),(6,8,10),(3,10,7)]

def ucgen_mi(s):
    for g in s:
        a, b, c = g
        if (a + b > c and a + c > b and c + b > a):
            return True
        else:
            return False


print(list(filter(ucgen_mi, liste)))

Traceback:

Traceback (most recent call last):
  File "D:Python ÇalışmalarÇalışmalarGömülü FonksiyonlarP2.py", line 30, in <module>
    print(list(filter(ucgen_mi, liste)))
  File "D:Python ÇalışmalarÇalışmalarGömülü FonksiyonlarP2.py", line 19, in ucgen_mi
    a, b, c = g
TypeError: cannot unpack non-iterable int object

I tried this way too, but the result is the same. It gives error on this line: for a,b,c in s:

for a,b,c in s:def ucgen_mi(s):
    for a,b,c in s:
        if (a + b > c and a + c > b and c + b > a):
            return True
        else:
            return False

To test the algorithm I wrote, I tried the bundles in the list separately and found that they were filtered the way I wanted.
`

liste = [(3,4,5)]

def ucgen_mi(s):
    for g in s:
        a, b, c = g
        if (a + b > c and a + c > b and c + b > a):
            return True
        else:
            return False

print(ucgen_mi(liste))
# result: True

Also:

liste = [(3,10,7)]

def ucgen_mi(s):
    for g in s:
        a, b, c = g
        if (a + b > c and a + c > b and c + b > a):
            return True
        else:
            return False

print(ucgen_mi(liste))
# result: False

Where am I doing wrong, can you help me?

Asked By: Batuhan Balaban

||

Answers:

The filter implicitly loops over the liste, therefore your function only needs to take care of a single element at a time:

def ucgen_mi(g):
    a, b, c = g
    if (a + b > c and a + c > b and c + b > a):
        return True
    else:
        return False

Example:

print(list(filter(ucgen_mi, [(3, 4, 5), (6, 8, 10), (3, 10, 7)])))

# result: [(3, 4, 5), (6, 8, 10)]

The error message TypeError: cannot unpack non-iterable int object can be understood as follows:

When filter checks whether the first element (3, 4, 5) meets the requirements, it is passed to ucgen_mi, therefore s equals (3, 4, 5). Then you loop over s (for g in s) and g becomes 3. Then you try to unpack g (a, b, c = g), which does not make sense (=> "cannot unpack non-iterable int object").

Answered By: mcsoini

filter function take, a function or None, and iterable.

here is doc of filter

class filter(object)
 |  filter(function or None, iterable) --> filter object
 |  
 |  Return an iterator yielding those items of iterable for which function(item)
 |  is true. If function is None, return the items that are true.

it take single iterable object from iterable (list/dict/tuple/generator) and do calculation on it ie it is kinda same as lambda x: x if func(x)

you need to modify the function such that, it calculate for each iterable object not whole list at a time.

below is a sample improved code

def ucgen_mi(array):
    a, b, c = array
    if (a+b > c) and (a+c > b) and (b+c>a):
            return True
    return False 
liste = [(3,4,5),(6,8,10),(3,10,7)] 
result = list(filter(ucgen_mi, liste))
print(result)
# [(3, 4, 5), (6, 8, 10)]
Answered By: sahasrara62