2011-01-25 3 views

ответ

10

Переход в первом направлении от [('a', 1), ('c', 3), ('b', 2)] до ['a',1,'c',3,'b',2] is flattening a list. Принимая принятый ответ от туда и модификация для этого примера:

>>> L = [('a', 1), ('c', 3), ('b', 2)] 
>>> list(itertools.chain(*L)) 
['a', 1, 'c', 3, 'b', 2] 

Это использует itertools.chain, который является хорошим средством от itertools, понижающих последовательностей довольно красиво.

Переход в обратном направлении будет проноситься:

>>> L = ['a', 1, 'c', 3, 'b', 2] 
>>> zip(L[0::2], L[1::2]) 
[('a', 1), ('c', 3), ('b', 2)] 

zip принимает два списка и сочетает в себе список 1 в первый элемент с списка 2 в первый элемент кортежа, и так далее вниз по длине списка. Так что в этом, мы в основном принимаем даже индексированные элементы, как наш первый список (L[0::2]), а затем нечетные индексированные элементы, как наш второго (L[1::2])

+2

Не забудьте 'itertools.izip_longest (* [ИТЭР (L)] * 2) '. ;-) – Apalala

+1

Кроме того, поскольку у вас уже есть 'itertools', вы можете либо' izip', либо 'zip' над' islice', чтобы не копировать список. – aaronasterling

3

Вот это мой взгляд на него (при условии, содержит первый список и б второй):

b = [] 
for i in a: 
    b.extend(i) 

и обратное:

c = [] 
for i in range(0, len(b) - 1, 2): 
    c.append((b[i], b[i+1])) 
+2

+1, FWIW, ваша версия первой имеет тенденцию быть быстрее, чем моя в моих тестах и ​​моя быстрее, чем ваша на втором - http://pastebin.com/SNrsqDmB –

+0

@ Даниэль: Будьте осторожны с преждевременной оптимизацией. –

+0

@Fred остерегайтесь куртизации груза. Выяснение того, какой путь быстрее, помогает изучать язык, поэтому вы можете записать его быстрым способом в первый раз. – aaronasterling

1
L = [('a', 1), ('c', 3), ('b', 2)] 
flat = [x for p in L for x in p] 
assert flat == ['a', 1, 'c', 3, 'b', 2] 

it = iter(flat) 
L2 = zip(it, it) 
assert L2 == L 

print "Success" 
+1

+1 для 'iter (flat)'. Это самый элегантный способ сделать это. – aaronasterling

1

есть уже много правильных ответов здесь, так что это просто напоминание не использовать сумму() для выравнивания списков, хотя это выглядит как аккуратное решение , к сожалению, производительность является квадратичной

In [1]: L=[('a',x) for x in range(10)] 

In [2]: timeit sum(L,()) 
100000 loops, best of 3: 2.78 us per loop 

In [3]: L=[('a',x) for x in range(100)] 

In [4]: timeit sum(L,()) 
10000 loops, best of 3: 108 us per loop 

In [5]: L=[('a',x) for x in range(1000)] 

In [6]: timeit sum(L,()) 
100 loops, best of 3: 8.02 ms per loop 
Смежные вопросы