Velocity Reviews > Converting a flat list to a list of tuples

Converting a flat list to a list of tuples

metiu uitem
Guest
Posts: n/a

 11-22-2005
Say you have a flat list:
['a', 1, 'b', 2, 'c', 3]

How do you efficiently get
[['a', 1], ['b', 2], ['c', 3]]

I was thinking of something along the lines of:
for (key,number) in list:
print key, number

but it's not working...

Thank you

Duncan Booth
Guest
Posts: n/a

 11-22-2005
metiu uitem wrote:

> Say you have a flat list:
> ['a', 1, 'b', 2, 'c', 3]
>
> How do you efficiently get
> [['a', 1], ['b', 2], ['c', 3]]

That's funny, I thought your subject line said 'list of tuples'. I'll
answer the question in the subject rather than the question in the body:

>>> aList = ['a', 1, 'b', 2, 'c', 3]
>>> it = iter(aList)
>>> zip(it, it)

[('a', 1), ('b', 2), ('c', 3)]

Steven D'Aprano
Guest
Posts: n/a

 11-22-2005
On Tue, 22 Nov 2005 02:57:14 -0800, metiu uitem wrote:

> Say you have a flat list:
> ['a', 1, 'b', 2, 'c', 3]
>
> How do you efficiently get
> [['a', 1], ['b', 2], ['c', 3]]

def split_and_combine(L):
newL = []
for i in range(len(L)//2):
newL.append( [L[2*i], L[2*i+1]] )
return newL

Another possibility is a list comprehension:

L = ['a', 1, 'b', 2, 'c', 3]
[[L[i], L[i+1]] for i in range(len(L)) if i%2 == 0]

Personally, I think that's just about as complex as a single list
comprehension should get. Otherwise it is too easy to create
unmaintainable code.

It is much easier (and probably faster) if you arrange matters so that you
have two lists at the start:

zip( ['a', 'b', 'c'], [1, 2, 3] )

returns [('a', 1), ('b', 2), ('c', 3)]

If you absolutely need the inner tuples to be lists, use a list
comprehension afterwards:
[list(t) for t in zip(['a', 'b', 'c'], [1, 2, 3])]

--
Steven.

metiu uitem
Guest
Posts: n/a

 11-22-2005
Thanks for the answer... yes the example was wrong!

Fredrik Lundh
Guest
Posts: n/a

 11-22-2005
"metiu uitem" wrote:

> Say you have a flat list:
> ['a', 1, 'b', 2, 'c', 3]
>
> How do you efficiently get
> [['a', 1], ['b', 2], ['c', 3]]

simplest possible (works in all Python versions):

L = ['a', 1, 'b', 2, 'c', 3]

out = []
for i in range(0, len(L), 2):
out.append(L[i:i+2])

or, on one line (works in all modern versions):

out = [L[i:i+2] for i in range(0, len(L), 2)]

or, from the slightly-silly-department:

out = map(list, zip(L[0::2], L[1::2]))

or, using the standard grouping pydiom:

out = []; item = []
for i in L:
item.append(i)
if len(item) == 2:
out.append(item)
item = []
if item:
out.append(item)

etc.

</F>

bonono@gmail.com
Guest
Posts: n/a

 11-22-2005

Duncan Booth wrote:
> metiu uitem wrote:
>
> > Say you have a flat list:
> > ['a', 1, 'b', 2, 'c', 3]
> >
> > How do you efficiently get
> > [['a', 1], ['b', 2], ['c', 3]]

>
> That's funny, I thought your subject line said 'list of tuples'. I'll
> answer the question in the subject rather than the question in the body:
>
> >>> aList = ['a', 1, 'b', 2, 'c', 3]
> >>> it = iter(aList)
> >>> zip(it, it)

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

brilliant.

Laurent Rahuel
Guest
Posts: n/a

 11-22-2005
metiu uitem wrote:

> Say you have a flat list:
> ['a', 1, 'b', 2, 'c', 3]
>
> How do you efficiently get
> [['a', 1], ['b', 2], ['c', 3]]
>
> I was thinking of something along the lines of:
> for (key,number) in list:
> print key, number
>
> but it's not working...
>
> Thank you

Hi,

newList = zip(aList[::2], aList[1::2])
newList
[('a', 1), ('b', 2), ('c', 3)]

Regards,

Laurent.

Steven D'Aprano
Guest
Posts: n/a

 11-22-2005
On Tue, 22 Nov 2005 11:11:23 +0000, Duncan Booth wrote:

>>>> aList = ['a', 1, 'b', 2, 'c', 3]
>>>> it = iter(aList)
>>>> zip(it, it)

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

I'm not sure if I should fall to my knees in admiration of a Cool Hack,
or recoil in horror at a Bogus Kludge

The code looks like it should return [('a', 'a'), (1, 1), ('b', 'b'), (2,
2), ('c', 'c'), (3, 3)] but of course it does not: the arguments for zip
are not independent.

I guess it is more of a Neat Trick, with a dash of Gotcha For The Unwary.

--
Steven.

Fredrik Lundh
Guest
Posts: n/a

 11-22-2005
Duncan Booth wrote:

> That's funny, I thought your subject line said 'list of tuples'. I'll
> answer the question in the subject rather than the question in the body:
>
> >>> aList = ['a', 1, 'b', 2, 'c', 3]
> >>> it = iter(aList)
> >>> zip(it, it)

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

yesterday, we got locals()["_[1]"]. and now this ?

is "relying on undefined behaviour" perhaps the new black ?

and people are impressed? it's like my old Z80 days, when
some folks thought it was truly amazing that call(11) printed
the raw contents of the entire memory to the screen...

</F>

=?ISO-8859-1?Q?Andr=E9?= Malo
Guest
Posts: n/a

 11-22-2005
* Duncan Booth <(E-Mail Removed)> wrote:

> metiu uitem wrote:
>
> > Say you have a flat list:
> > ['a', 1, 'b', 2, 'c', 3]
> >
> > How do you efficiently get
> > [['a', 1], ['b', 2], ['c', 3]]

>
> That's funny, I thought your subject line said 'list of tuples'. I'll
> answer the question in the subject rather than the question in the body:
>
> >>> aList = ['a', 1, 'b', 2, 'c', 3]
> >>> it = iter(aList)
> >>> zip(it, it)

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

Though it looks nice, it's an implementation dependant solution. What if
someone changes zip to fetch the second item first?

nd