如何解压由 zip() 创建的列表
How to unpack the list created by zip()
我有两个列表,我将它们 zip() 在一起:
>> 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
是一个空列表 []
。
刚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 returns 一次性使用迭代器。这就是每次使用后都需要再次调用 zip 的原因(仅在 Python 3 中)
zip
函数returns一个迭代器。 print(list(zipped))
调用因此运行迭代器直到结束,下一个 zip(*zipped)
没有任何东西可以吃。
最终问题根本不在于 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
异常。但那只是因为你的上下文是空的,你的测试成功了!
我有两个列表,我将它们 zip() 在一起:
>> 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
是一个空列表 []
。
刚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 returns 一次性使用迭代器。这就是每次使用后都需要再次调用 zip 的原因(仅在 Python 3 中)
zip
函数returns一个迭代器。 print(list(zipped))
调用因此运行迭代器直到结束,下一个 zip(*zipped)
没有任何东西可以吃。
最终问题根本不在于 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
异常。但那只是因为你的上下文是空的,你的测试成功了!