【问题标题】:How to unpack the list created by zip()如何解压 zip() 创建的列表
【发布时间】:2017-01-07 03:21:12
【问题描述】:

我有两个我 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)

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

{% for season, commissioner in pools %}

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

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

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

【问题讨论】:

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


    【解决方案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】:

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

      【讨论】:

      • 也许发生了同样的事情:测试框架或 Django 代码中的某些东西可能正在监视 context 对象,在你得到它之前就使用了迭代器。试试context['pools'] = list(zip(context['pools'], commissioner)) ?
      【解决方案3】:

      最终问题根本不在于 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 异常。但这只是因为您的上下文是空的并且您的测试有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-15
        相关资源
        最近更新 更多