Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #51103 > unrolled thread
| Started by | steve@divillo.com |
|---|---|
| First post | 2013-07-23 14:52 -0700 |
| Last post | 2013-07-24 11:11 -0700 |
| Articles | 9 — 7 participants |
Back to article view | Back to comp.lang.python
Converting a list of lists to a single list steve@divillo.com - 2013-07-23 14:52 -0700
Re: Converting a list of lists to a single list Rafael Durán Castañeda <rafadurancastaneda@gmail.com> - 2013-07-24 00:34 +0200
Re: Converting a list of lists to a single list MRAB <python@mrabarnett.plus.com> - 2013-07-23 23:52 +0100
Re: Converting a list of lists to a single list Zero Piraeus <schesis@gmail.com> - 2013-07-23 18:49 -0400
Re: Converting a list of lists to a single list Terry Reedy <tjreedy@udel.edu> - 2013-07-23 19:02 -0400
Re: Converting a list of lists to a single list Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-07-23 20:28 -0400
Re: Converting a list of lists to a single list Chris Angelico <rosuav@gmail.com> - 2013-07-24 15:40 +1000
Re: Converting a list of lists to a single list Terry Reedy <tjreedy@udel.edu> - 2013-07-24 11:56 -0400
Re: Converting a list of lists to a single list steve@divillo.com - 2013-07-24 11:11 -0700
| From | steve@divillo.com |
|---|---|
| Date | 2013-07-23 14:52 -0700 |
| Subject | Converting a list of lists to a single list |
| Message-ID | <ee6f5c48-6cb1-498f-813a-be2eef5411fc@googlegroups.com> |
I think that itertools may be able to do what I want but I have not been able to figure out how. I want to convert an arbitrary number of lists with an arbitrary number of elements in each list into a single list as follows. Say I have three lists: [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]] I would like to convert those to a single list that looks like this: [A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2] An easier way to visualize the pattern I want is as a tree. A0 B0 C0 C1 C2 B1 C0 C1 C2 B2 C0 C1 C2 A1 B0 C0 C1 C2 B1 C0 C1 C2 B2 C0 C1 C2 A2 B0 C0 C1 C2 B1 C0 C1 C2 B2 C0 C1 C2
[toc] | [next] | [standalone]
| From | Rafael Durán Castañeda <rafadurancastaneda@gmail.com> |
|---|---|
| Date | 2013-07-24 00:34 +0200 |
| Message-ID | <mailman.5015.1374618881.3114.python-list@python.org> |
| In reply to | #51103 |
El 23/07/13 23:52, steve@divillo.com escribió: > [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]] Hi, I think you are looking for itertools.chain, or in this case, itertools.chain.from_iterable: In [1]: x = [['A0','A1','A2'], ['B0','B1','B2'], ['C0','C1','C2']] In [2]: import itertools In [3]: [ y for y in itertools.chain.from_iterable(x)] Out[3]: ['A0', 'A1', 'A2', 'B0', 'B1', 'B2', 'C0', 'C1', 'C2'] HTH
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2013-07-23 23:52 +0100 |
| Message-ID | <mailman.5017.1374619944.3114.python-list@python.org> |
| In reply to | #51103 |
On 23/07/2013 22:52, steve@divillo.com wrote:
> I think that itertools may be able to do what I want but I have not been able to figure out how.
>
> I want to convert an arbitrary number of lists with an arbitrary number of elements in each list into a single list as follows.
>
> Say I have three lists:
>
> [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]]
>
> I would like to convert those to a single list that looks like this:
>
> [A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2]
>
> An easier way to visualize the pattern I want is as a tree.
>
> A0
> B0
> C0
> C1
> C2
> B1
> C0
> C1
> C2
> B2
> C0
> C1
> C2
> A1
> B0
> C0
> C1
> C2
> B1
> C0
> C1
> C2
> B2
> C0
> C1
> C2
> A2
> B0
> C0
> C1
> C2
> B1
> C0
> C1
> C2
> B2
> C0
> C1
> C2
>
Using recursion:
def tree_list(items):
if len(items) == 1:
return items[0]
sublist = tree_list(items[1 : ])
result = []
for item in items[0]:
result.append(item)
result.extend(sublist)
return result
items = [["A0","A1","A2"], ["B0","B1","B2"], ["C0","C1","C2"]]
print(tree_list(items))
[toc] | [prev] | [next] | [standalone]
| From | Zero Piraeus <schesis@gmail.com> |
|---|---|
| Date | 2013-07-23 18:49 -0400 |
| Message-ID | <mailman.5018.1374620275.3114.python-list@python.org> |
| In reply to | #51103 |
:
On 23 July 2013 17:52, <steve@divillo.com> wrote:
>
> Say I have three lists:
>
> [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]]
>
> I would like to convert those to a single list that looks like this:
>
[A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2]
How's this:
from itertools import chain
def treeify(seq):
if seq:
return list(chain(*([x] + treeify(seq[1:]) for x in seq[0])))
else:
return []
>>> treeify([['A0', 'A1', 'A2'], ['B0', 'B1', 'B2'], ['C0', 'C1', 'C2']])
['A0', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2', 'C0', 'C1', 'C2',
'A1', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2', 'C0', 'C1', 'C2',
'A2', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2', 'C0', 'C1', 'C2']
-[]z.
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-07-23 19:02 -0400 |
| Message-ID | <mailman.5019.1374620579.3114.python-list@python.org> |
| In reply to | #51103 |
On 7/23/2013 5:52 PM, steve@divillo.com wrote:
> I think that itertools may be able to do what I want but I have not
> been able to figure out how.
A recursive generator suffices.
> I want to convert an arbitrary number of lists with an arbitrary
> number of elements in each list into a single list as follows.
>
> Say I have three lists:
>
> [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]]
>
> I would like to convert those to a single list that looks like this:
>
> [A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,
> A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,
> A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2]
def crossflat(lofl):
if lofl:
first = lofl.pop(0)
for o in first:
yield o
yield from crossflat(lofl.copy())
A0, A1, A2 = 100, 101, 102
B0, B1, B2 = 10, 11, 12
C0, C1, C2 = 0, 1, 2
LL = [[A0, A1, A2], [B0, B1, B2], [C0, C1, C2]]
cfLL = list(crossflat(LL))
print(cfLL)
assert cfLL == [
A0, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2,
A1, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2,
A2, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2]
passes
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2013-07-23 20:28 -0400 |
| Message-ID | <mailman.5023.1374625711.3114.python-list@python.org> |
| In reply to | #51103 |
On Wed, 24 Jul 2013 00:34:31 +0200, Rafael Durán Castañeda
<rafadurancastaneda@gmail.com> declaimed the following:
>El 23/07/13 23:52, steve@divillo.com escribió:
>> [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]]
>Hi,
>
>I think you are looking for itertools.chain, or in this case,
>itertools.chain.from_iterable:
>
>In [1]: x = [['A0','A1','A2'], ['B0','B1','B2'], ['C0','C1','C2']]
>
>In [2]: import itertools
>
>In [3]: [ y for y in itertools.chain.from_iterable(x)]
>Out[3]: ['A0', 'A1', 'A2', 'B0', 'B1', 'B2', 'C0', 'C1', 'C2']
>
No, that just flattened the lists... The OP example shows the third
list is repeated after each element of the second list, and the flattened
result of that is then repeated for each element of the first list (and
flattened).
op> I would like to convert those to a single list that looks like this:
op>
op>
[A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2]
op>
-=-=-=-=-=-
inp = [ ["%s%s" % (a,o) for o in "012"] for a in "ABC"]
print inp
def repFlatten(LoL): #LoL List of Lists
if not LoL or (type(LoL) != type([])
or type(LoL[0]) != type([])):
return LoL
res = []
for itm in LoL[0]:
res.append(itm)
res.extend(repFlatten(LoL[1:]))
return res
print repFlatten(inp)
-=-=-=-=-=-
[['A0', 'A1', 'A2'], ['B0', 'B1', 'B2'], ['C0', 'C1', 'C2']]
['A0', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2', 'C0', 'C1',
'C2', 'A1', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2', 'C0',
'C1', 'C2', 'A2', 'B0', 'C0', 'C1', 'C2', 'B1', 'C0', 'C1', 'C2', 'B2',
'C0', 'C1', 'C2']
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-07-24 15:40 +1000 |
| Message-ID | <mailman.5025.1374644439.3114.python-list@python.org> |
| In reply to | #51103 |
On Wed, Jul 24, 2013 at 8:34 AM, Rafael Durán Castañeda <rafadurancastaneda@gmail.com> wrote: > In [3]: [ y for y in itertools.chain.from_iterable(x)] > Out[3]: ['A0', 'A1', 'A2', 'B0', 'B1', 'B2', 'C0', 'C1', 'C2'] Complete aside, given that this has already been pointed out as solving a different problem: Any time you see a list comp that just does "[ x for x in foo ]", check to see if it can be replaced by a simple list constructor: >>> [ y for y in itertools.chain.from_iterable(x)] ['A0', 'A1', 'A2', 'B0', 'B1', 'B2', 'C0', 'C1', 'C2'] >>> list(itertools.chain.from_iterable(x)) ['A0', 'A1', 'A2', 'B0', 'B1', 'B2', 'C0', 'C1', 'C2'] A bit simpler and achieves the same. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-07-24 11:56 -0400 |
| Message-ID | <mailman.5047.1374681415.3114.python-list@python.org> |
| In reply to | #51103 |
On 7/23/2013 7:02 PM, Terry Reedy wrote:
> On 7/23/2013 5:52 PM, steve@divillo.com wrote:
>> I think that itertools may be able to do what I want but I have not
>> been able to figure out how.
What you want is a flattened product with unchanged components of the
successive products omitted in the flattening. The omission is the
difficulty.
> A recursive generator suffices.
But see below for how to use itertools.product.
>> I want to convert an arbitrary number of lists with an arbitrary
>> number of elements in each list into a single list as follows.
While others answered the Python2-oriented question ("How do I produce a
list from a list of lists"), I answered the Python-3 oriented question
of how to produce an iterator from an iterable of iterables. This scales
better to an input with lots of long sequences. There is usually no need
to manifest the output as a list, as the typical use of the list will be
to iterate it.
> def crossflat(lofl):
> if lofl:
> first = lofl.pop(0)
> for o in first:
> yield o
> yield from crossflat(lofl.copy())
>
> A0, A1, A2 = 100, 101, 102
> B0, B1, B2 = 10, 11, 12
> C0, C1, C2 = 0, 1, 2
> LL = [[A0, A1, A2], [B0, B1, B2], [C0, C1, C2]]
> cfLL = list(crossflat(LL))
> print(cfLL)
> assert cfLL == [
> A0, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2,
> A1, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2,
> A2, B0, C0, C1, C2, B1, C0, C1, C2, B2, C0, C1, C2]
>
> passes
Here is filtered flattened product version. I think it clumsier than
directly producing the items wanted, but it is good to know of this
approach as a backup.
from itertools import product
def flatprod(iofi): # iterable of iterables
lofi = list(iofi)
now = [object()] * len(lofi)
for new in product(*lofi):
i = 0
while now[i] == new[i]:
i += 1
yield from new[i:]
now = new
cfLL = list(flatprod(LL))
Same assert as before passes.
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | steve@divillo.com |
|---|---|
| Date | 2013-07-24 11:11 -0700 |
| Message-ID | <2f857fe1-256f-48e7-9ad6-b686c84d32d6@googlegroups.com> |
| In reply to | #51103 |
Wow, thanks everyone. Very helpful indeed! On Tuesday, July 23, 2013 2:52:21 PM UTC-7, st...@divillo.com wrote: > I think that itertools may be able to do what I want but I have not been able to figure out how. > > > > I want to convert an arbitrary number of lists with an arbitrary number of elements in each list into a single list as follows. > > > > Say I have three lists: > > > > [[A0,A1,A2], [B0,B1,B2] [C0,C1,C2]] > > > > I would like to convert those to a single list that looks like this: > > > > [A0,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A1,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2,A2,B0,C0,C1,C2,B1,C0,C1,C2,B2,C0,C1,C2] > > > > An easier way to visualize the pattern I want is as a tree. > > > > A0 > > B0 > > C0 > > C1 > > C2 > > B1 > > C0 > > C1 > > C2 > > B2 > > C0 > > C1 > > C2 > > A1 > > B0 > > C0 > > C1 > > C2 > > B1 > > C0 > > C1 > > C2 > > B2 > > C0 > > C1 > > C2 > > A2 > > B0 > > C0 > > C1 > > C2 > > B1 > > C0 > > C1 > > C2 > > B2 > > C0 > > C1 > > C2
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web