2016-08-30 2 views
1

У меня есть два списка, я Zip() вместе:Как распаковать список, созданный почтовый индекс()

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

Как и ожидалось, до сих пор:

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

Из документов, похоже, Я могу только сделать это, чтобы получить обратно два списка из почтового объекта:

>> 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.

Edit:

Как @daragua указывает ниже, печать (список (Молнии)) фактически потребляя архивный объект, таким образом, делая его пустым. Это правда, для моего простого примера. У меня все еще проблема с моим настоящим кодом.

Что я пытаюсь написать единичный тест для представления 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 является пустым списком [].

ответ

2

Функция zip возвращает итератор. Таким образом, вызов print(list(zipped)) запускает итератор до конца, а следующий zip(*zipped) не имеет ничего, чтобы поесть.

+0

Возможно, это одно и то же: что-то в рамках тестирования или в коде Django может зацикливаться на объекте 'context', потребляя итератор, прежде чем вы его получите. Попробуйте 'context ['pools'] = list (zip (context ['pools'], комиссар))'? – daragua

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'] 

Side Примечание: В Python 3, ZIP возвращается одноразовый итератор. Вот почему zip необходимо вызывать снова после каждого использования (только в Python 3)

0

В конечном счете проблема не была связана с объектом 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 исключение. Но это только потому, что ваш контекст пуст, и ваш тест сработал!

Смежные вопросы