2017-04-11 1 views
1

Ich habe eine Liste von Listen von Listen mit Streichern, so etwas wie dies (die Kapitel, Absätze und Sätze eines Textes)):, wie Listen glätten, während einige Verschachtelung (in Python) verlassen

[ [[ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'] ], 
    [ ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ]], 
    [[ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'] ], 
    [ ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ]] ] 

I wissen, wie diese Liste vollständig zu glätten (zB durch [x for y in z for x in y]), aber was würde ich mag zu tun ist es teilweise abzuflachen, um schließlich wie folgt aussehen:

[ [ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'], 
    ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ], 
    [ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'], 
    ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ] ] 

ich es geschafft, dies für Schleifen durch einige zu lösen:

semiflattend_list=list() 
for chapter in chapters: 
    senlist=list() 
    for paragraph in chapter: 
     for sentences in paragraph: 
      senlist.append(sentences) 
    semiflattend_list.append(senlist) 

Aber ich frage mich, ob es eine bessere, kürzere Lösung gibt? (Ich glaube, nicht zip ist ein Weg zu gehen, weil meine Listen unterschiedlich in der Größe.)

+1

Die Beispiele, die Sie gaben, ist eigentlich ein Tupel von zwei verschiedenen Listen, die ich glaube nicht, was Sie meinten. Sie vermasseln vielleicht die Klammern oder ein Komma, aber wir brauchen ein überprüfbares Beispiel –

Antwort

1

Die einfachste Veränderung, die ich sehen kann, ist mit der itertools.chain Methode:

q = [ 
    [[ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'] ], 
     [ ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ]], 
    [[ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'] ], 
     [ ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ]] 
    ] 

r = [list(itertools.chain(*g)) for g in q] 
print(r) 

[[['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'], ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3']], 
[['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'], ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3']]] 

Also, was tut [list(itertools.chain(*g)) for g in q] Mittelwert:

# If I only had this 
[g for g in q] 
# I would get the same I started with. 
# What I really want is to expand the nested lists 

# * before an iterable (basically) converts the iterable into its parts. 
func foo(bar, baz): 
    print(bar + " " + baz) 

lst = ["cat", "dog"] 
foo(*lst) # prints "cat dog" 

# itertools.chain accepts an arbitrary number of lists, and then outputs 
# a generator of the results: 
c = itertools.chain([1],[2]) 
# c is now <itertools.chain object at 0x10e1fce10> 
# You don't want an generator though, you want a list. Calling `list` converts that: 
o = list(c) 
# o is now [1,2] 
# Now, together: 
myList = [[2],[3]] 
flattened = list(itertools.chain(*myList)) 
# flattened is now [2,3] 
+0

Das hat es tatsächlich gelöst! Könnten Sie bitte bitte diesen Asterisk/Splat Operator erklären? In der [doc] (https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists) erklärt es mir nicht, wie das hier helfen könnte. – dia