Search code examples
djangopython-3.xdjango-testing

How to unpack the list created by zip()


I have two lists that I zip() together:

>> x1 = ['1', '2', '3']
>> y1 = ['a', 'b', 'c']
>> zipped = zip(x1, y1)

As expected so far:

>> print(list(zipped)
[('1', 'a'), ('2', 'b'), ('3', 'c')]

From the docs, it seems like I can just do this to get back the two lists from the zip object:

>> x2, y2 = zip(*zipped)

But instead I get the error:

Traceback (most recent call last):    
File "/usr/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2869, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)    
File "<ipython-input-6-58fe68d00d1c>", line 1, in <module>
x2, y2 = zip(*zipped)
ValueError: not enough values to unpack (expected 2, got 0)

Obviously I'm not understanding something simple about the zip object.

Edit:

As @daragua points out below, the print(list(zipped)) was actually consuming the zipped object, thus making it empty. That's true, for my simple example. I'm still having an issue with my real code.

What I'm trying to to is write a unit test for Django view that has a zipped object in it's context. The view works fine, I'm just struggling writing the test for it.

In my view context I have this:

for season in context['pools']:
    commissioner.append(season.pool.is_commish(self.request.user))
context['pools'] = zip(context['pools'], commissioner)

This works as expected. The pools context object is two lists, which the template handles just fine:

{% for season, commissioner in pools %}

The test I'm struggling to write is to check if the commissioner value is correct for a the pool object for the logged in user. In my test:

context = self.response.context['pools']
print(list(context ))

In this case, context is an empty list [].


Solution

  • The zip function returns an iterator. The print(list(zipped)) call thus runs the iterator til its end and the next zip(*zipped) doesn't have anything to eat.