how could i change [('a', 1), ('c', 3), ('b', 2)]
to ['a',1,'c',3,'b',2]
and vice versa?
Thanks

- 23,614
- 16
- 68
- 106

- 21
- 2
4 Answers
Going in the first direction from [('a', 1), ('c', 3), ('b', 2)]
to ['a',1,'c',3,'b',2]
is flattening a list. Taking the accepted answer from there and modifying for this example:
>>> L = [('a', 1), ('c', 3), ('b', 2)]
>>> list(itertools.chain(*L))
['a', 1, 'c', 3, 'b', 2]
This uses itertools.chain
which is a nice tool from itertools
that flattens sequences quite nicely.
Going the opposite way is zipping:
>>> L = ['a', 1, 'c', 3, 'b', 2]
>>> zip(L[0::2], L[1::2])
[('a', 1), ('c', 3), ('b', 2)]
zip
takes two lists and combines list 1's first element with list 2's first element in a tuple, and so on down the lengths of the list. So in this one, we basically take the even-indexed elements as our first list (L[0::2]
), and then the odd-indexed elements as our second (L[1::2]
)

- 1
- 1

- 55,313
- 14
- 116
- 115
-
2Don't forget `itertools.izip_longest(*[iter(L)]*2)`. ;-) – Apalala Jan 25 '11 at 23:39
-
1Also, since you already have `itertools` laying around, you can either `izip` or `zip` over `islice` to avoid having to copy the list. – aaronasterling Jan 26 '11 at 00:27
Here it's my take on it (assuming a contains first list and b second):
b = []
for i in a:
b.extend(i)
And reverse:
c = []
for i in range(0, len(b) - 1, 2):
c.append((b[i], b[i+1]))

- 3,629
- 1
- 19
- 13
-
2+1, FWIW, your version of the first tends to be faster than mine in my tests and mine faster than yours on the second - http://pastebin.com/SNrsqDmB – Daniel DiPaolo Jan 25 '11 at 23:24
-
-
@Fred beware of cargo cult quoting. Figuring out which way is faster helps to learn the language so you can write it the fast way the first time. – aaronasterling Jan 26 '11 at 00:28
-
@aaronasterling: Figuring out [what needs to be optimized](http://programmers.stackexchange.com/q/816) instead of worrying about what doesn't is how you write it the fast way. – Fred Nurk Jan 26 '11 at 00:44
-
@Fred Nurk Figuring out what needs to be optimized only needs to be done if it's too slow. It won't be to slow if you write it the right way the first time. Obsessively profiling code and looking at internals is how you figure it out. I'm talking about building general knowledge here, not optimizing a particular program. – aaronasterling Jan 26 '11 at 01:06
-
@aaronasterling: I don't see *any* general knowledge about optimization to be gained from micro-optimizing a 6 item list. I say micro-optimizing because the above is looking at one very specific made-up situation rather than algorithms, clarity (which goes to code generality), etc. – Fred Nurk Jan 26 '11 at 01:41
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"

- 13,952
- 4
- 37
- 63
There are already plenty of correct answers here, so this is just a reminder not to use sum() to flatten lists as although it looks like a neat solution unfortunately the performance is quadratic
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

- 295,403
- 53
- 369
- 502