pstatix
pstatix

Reputation: 3848

Trouble unpacking returned tuple during list comprehension

I've got a function that takes input and returns a 3 item tuple:

def f(a, b):
    x = a + 1
    y = x + 2
    z = y + 3
    return (x, y, z)

And I start with a set of tuples:

my_set = {(1, 2), (3, 4), ... (m, n)}

And I need to build a list, but the follow throws a TypeError:

[(a, b, x, y, z, (x, y, z)) for a, b in my_set for x, y, z in f(a, b)]
TypeError: 'int' object is not iterable

I was reviewing this post which shows a similar process, but for some reason the for x, y, z ... is throwing the exception and I'm not sure if I am just overlooking something small or not.

Upvotes: 3

Views: 93

Answers (2)

koPytok
koPytok

Reputation: 3713

Let's understand your one-liner. Here's what you're actually doing:

for a, b in my_set:
    for i in f(a, b):
        print(i)

For every a & b in my_set function f is calculated. It outputs a tuple and then i is iterated over the tuple.

Because every item in the tuple is an integer,for x, y, z in f(a, b) doesn't work. Integer can't be split into several fractions.

You need:

[(a, b, *f(a, b), f(a, b)) for a, b in my_set]

In case efficiency matters you need for loop:

output = list()
for a, b in my_set:
    x, y, z = f(a, b)
    output.append((a, b, x, y, z, (x, y, z))

Upvotes: 1

user2357112
user2357112

Reputation: 281330

It's valid to unpack f(a, b) into x, y, z, but that's not what you're doing. for x, y, z in f(a, b) attempts to unpack each element of f(a, b) as if each element was an individual 3-tuple.

What you're looking for is a way to assign f(a, b) to something in a list comprehension, without iterating over it. There are workarounds for that, but I'd recommend just using a normal loop:

l = []
for a, b in my_set:
    x, y, z = f(a, b)
    l.append((a, b, x, y, z, (x, y, z)))

If you really want to use a list comprehension, one workaround is to loop over a dummy list [f(a, b)] instead of f(a, b):

[(a, b, x, y, z, (x, y, z)) for a, b in my_set for x, y, z in [f(a, b)]]

Upvotes: 5

Related Questions