Reputation: 3848
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
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
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