Zach Gates
Zach Gates

Reputation: 4130

How can I unpack four variables from a list?

I have this list:

varlist = ['1', 'King', 't', '1']

I'm trying to unpack these four variables in a for loop;

for var1, var2, var3, var4 in varlist:
    post += len(var1)-len(var3)
    post *= len(var2)/len(var4)

When I run this loop, I get the following:

ValueError: need more than 1 value to unpack

How can I fix this?

Upvotes: 2

Views: 139

Answers (4)

detly
detly

Reputation: 30332

Unpacking is different from iteration. You need to do this:

var1, var2, var3, var4 = varlist
post += len(var1)-len(var3)
post *= len(var2)/len(var4)

No loop is needed here.

Upvotes: 8

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

varlist = ['1', 'King', 't', '1']

for i,j,k,l in zip(*[iter(varlist)]*4):
    print i,j,k,l
1 King t 1

The *4 is the amount of elements you want, if you had a list like varlist=[1, 2, 3, 4, 5, 6, 7, 8,9,10]

It will zip four elements in a step of 4 giving the output:

1 2 3 4
5 6 7 8

The elements in your list must be a multiple of the variables you are assigning them to or you will not get all the elements as shown in the ouput above.

Upvotes: 1

Dair
Dair

Reputation: 16240

I don't think you don't want unpack, you want a way to group the list, and access the individual elements of the grouping which can be done with grouper:

from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

post = 0

varlist = ['1', 'King', 't', '1', 'lol', 'newbs', 'money', 'plox']

print list(grouper(varlist, 4))

# Prints: [('1', 'King', 't', '1'), ('lol', 'newbs', 'money', 'plox')]

for var1, var2, var3, var4 in grouper(varlist, 4):
    post += len(var1)-len(var3)
    post *= len(var2)/len(var4)

print post

# Prints: -2

Upvotes: 2

Adam Smith
Adam Smith

Reputation: 54173

You can't actually do this. There's a quick hack to make it work the way you think it will, but ultimately what you're trying to do doesn't work. Here's the quick hack:

varlist = ['1', 'King', 't', '1']
for var1, var2, var3, var4 in [varlist]: # note the brackets
    post += len(var1)-len(var3)
    post *= len(var2)\len(var4) # note that this line fails, because \ isn't /

The reason you can't do this is that a for loop iterates through each element in an iterable and assigns that value to whatever you tell it to. In this case, the first element in varlist is '1', not ('1','King','t','1'). By doing for <stuff> in [varlist] you wrap your current varlist in another list, and iterate on that instead. The first element of THAT is ['1','King','t','1'], which is unpackable into var1, var2, var3, var4.

I'd strongly recommend rethinking your design, however, if this is really what you want to do. This sounds great if you have a lot of varlists, otherwise just do:

var1, var2, var3, var4 = varlist # unpack without the loop
post += len(var1) - len(var3)
post *= len(var2) / len(var4)

Upvotes: 5

Related Questions