2016-02-17 3 views
3

У меня есть список кортежей:2 элементов из списка кортежей

Items = [(4, 2), (1, 1), (2, 4), (8, 6), (11, 4), (10, 2), (7, 3), (6, 1)] 

, и я хочу, чтобы получить его, как это в for цикле:

NewItems = [[(4, 2), (1, 1)], 
      [(2, 4), (8, 6)], 
      [(11, 4), (10, 2)], 
      [(7, 3), (6, 1)]] 

Я сделал это:

NewItems = [] 
while len(Items) > 0: 
    NewItems.append([Items[0], Items[1]]) 
    del Items[0:2] 
print NewItems 

Я не думаю, что это лучший способ, так как я удаляю Items переменных. Затем я попытался сделать это:

newList = iter(Items) 
NewItems = [] 
for a, b in zip(newList, newList): 
    NewItems.append([a, b]) 
print NewItems 

но это слияние кортежей.

Есть ли лучшее решение, которое может сделать то же самое?

+1

Вы можете сделать список кортежей, как это, 'молнии (товары, товары [1:])' – Dharmik

+0

Что случилось с ITER версии? Кажется, он генерирует желаемый результат. Очевидно, вам не нужен явный цикл for только для понимания списка 'NewItems = [list (x) для x в zip (newList, newList)]'. И если вы не против кортежей вместо списков, то еще проще: 'NewItems = list (zip (newList, newList))'. Версия iter позволяет избежать создания каких-либо промежуточных списков, поэтому мой предпочтительный подход. – AChampion

+0

@AChampion да, это была моя ошибка, я должен просто использовать одну переменную из цикла и добавить ее в список. – Bear

ответ

3

Вы можете использовать представление списка, в котором вы можете закрепить элементы в парах.

Items = [(4, 2), (1, 1), (2, 4), (8, 6), (11, 4), (10, 2), (7, 3), (6, 1)] 
New_Items = [list(pair) for pair in zip(Items[::2], Items[1::2])] 

>>> New_Items 
[[(4, 2), (1, 1)], [(2, 4), (8, 6)], [(11, 4), (10, 2)], [(7, 3), (6, 1)]] 
2
>>> items = [(4,2),(1,1),(2,4),(8,6),(11,4),(10,2),(7,3),(6,1)] 
>>> new_items = [items[i:i+2] for i in range(0, len(items), 2)] 
>>> new_items 
[[(4, 2), (1, 1)], [(2, 4), (8, 6)], [(11, 4), (10, 2)], [(7, 3), (6, 1)]] 

Вы можете сделать это с помощью цикла while.

>>> new_items = [] 
>>> while items: 
...  new_items.append((items.pop(0), items.pop(0))) 
... 
>>> new_items 
[((4, 2), (1, 1)), ((2, 4), (8, 6)), ((11, 4), (10, 2)), ((7, 3), (6, 1))] 

Однако это разрушительно для items и не очень эффективен в связи с использованием pop(0), который O (п)

4

Если вы не возражаете кортежи кортежей вместо внутренних списков, просто пронестись вверху:

>>> zip(Items[0::2], Items[1::2]) 
[((4, 2), (1, 1)), ((2, 4), (8, 6)), ((11, 4), (10, 2)), ((7, 3), (6, 1))] 
+1

Вы можете сделать их списки, просто обернув их в 'map (list, ....)' –

+0

Просто обратите внимание, что ни один из них не возвращает 'list' в py3. OP использовал py2.7, поэтому не проблема, а 'list (zip (...))' переносима. – AChampion

1
from time import time 

Items = [(4,2),(1,1),(2,4),(8,6),(11,4),(10,2),(7,3),(6,1)] 
NewItems = [] 
start_time = time() 
while len(Items) > 0 : 
    NewItems.append([Items[0],Items[1]]) 
    del Items[0:2] 
print NewItems 
print time() - start_time 

Items = [(4,2),(1,1),(2,4),(8,6),(11,4),(10,2),(7,3),(6,1)] 
NewItems = [] 
start_time = time() 
for i in range(len(Items)/2): 
    NewItems.append([Items[2*i],Items[2*i + 1]]) 
print NewItems 
print time() - start_time 

С некоторыми времени, так что вы можете проверить, что второе решение быстрее

2

Как насчет

Items = [(4,2),(1,1),(2,4),(8,6),(11,4),(10,2),(7,3),(6,1)] 

NewItems = [] 
j =0 
for i in xrange(1,len(Items)-1): 
    if j+1 > len(Items): 
     break 
    NewItems.append([Items[j],Items[j+1]]) 
    j += 2 

print NewItems 
+0

Это по-прежнему дает неправильный результат. '[[(1, 1), (2, 4)], [(2, 4), (8, 6)], [(8, 6), (11, 4)]]' – Alexander

+0

[[(4 , (1, 1)], [(2, 4), (8, 6)], [(11, 4), (10, 2)], [(7, 3), (6, 1))]] – yael

0

Еще один подход, но, вероятно, не самый красивый.

x = [] 
i = iter(Items) 

while True: 
    try: 
     x.append([i.next(), i.next()]) 
    except StopIteration: 
     break 
Смежные вопросы