如何解压缩zip()创建的列表

时间:2016-08-30 18:05:53

标签: django python-3.x django-testing

我有两个拉链()列表:

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

到目前为止的预期:

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

从文档中,似乎我可以这样做以从zip对象中取回两个列表:

>> x2, y2 = zip(*zipped)

但我得到了错误:

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)

显然我不了解zip对象的简单内容。

编辑:

正如@daragua在下面指出的那样,print(list(zipped))实际上正在使用压缩对象,从而使它变空。对我的简单例子来说,这是真的。我的真实代码仍然存在问题。

我正在尝试为Django视图编写一个单元测试,在其上下文中有一个压缩对象。视图很好,我只是在努力为它编写测试。

在我看来,我有这个:

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

这可以按预期工作。池上下文对象是两个列表,模板处理得很好:

{% for season, commissioner in pools %}

我正在努力编写的测试是检查登录用户的池对象的commissioner值是否正确。在我的测试中:

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

在这种情况下,context是一个空列表[]

3 个答案:

答案 0 :(得分:2)

zip函数返回一个迭代器。 print(list(zipped))调用因此运行迭代器直到结束,下一个zip(*zipped)没有任何东西可以吃。

答案 1 :(得分:1)

只需zip回到反向:

>>> zipped=zip(x1, y1)
>>> x2, y2=zip(*zipped)
>>> x2
('1', '2', '3')

如果您希望结果是列表而不是元组,请使用map

>>> zipped=zip(x1, y1)
>>> x2, y2=map(list, zip(*zipped))
>>> x2
['1', '2', '3']
>>> y2
['a', 'b', 'c']

附注:在Python 3中,zip返回一次性使用迭代器。这就是每次使用后需要再次调用zip的原因(仅限Python 3)

答案 2 :(得分:0)

最终问题不在于zip对象。

如果要将zip对象发送到Django上下文:

x = ['1', '2', '3']
y = ['a', 'b', 'c']
context['zipped'] = zip(x, y)

如果您正在尝试为上下文数据编写单元测试,则无需解压缩,因为它可以从已解压缩的响应上下文中提取:

def test_zipped_data(TestCase):
    x, y = self.response.context_data['zipped']
    self.assertIn('b', y)

但是,如果您的上下文数据为空(zipped == []),那么您将获得ValueError例外。但那只是因为你的背景是空的,你的测试工作了!