2012-04-12 6 views
12

Normalerweise möchten Sie den umgekehrten Weg gehen, like here. Ich habe mich gefragt, wie Sie eine flache Liste in eine Liste der Liste umwandeln können, quasy Umformen Array in PythonKonvertieren Sie eine flache Liste in Liste der Liste in Python

In numpy Sie so etwas wie tun könnten:

>>> a=numpy.aranage(9) 
>>> a.reshape(3,3) 
>>> a 
array([[0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8]]) 

Ich habe mich gefragt, wie Sie das Gegenteil tun, und Meine übliche Lösung ist so etwas wie:

>>> Mylist 
['a', 'b', 'c', 'd', 'e', 'f'] 
>>> newList = [] 
for i in range(0,len(Mylist),2): 
...  newList.append(Mylist[i], Mylist[i+1]) 
>>> newList 
[['a', 'b'], ['c', 'd'], ['e', 'f']] 

Gibt es einen "Pythonic" Weg, es zu tun?

+0

ist es am besten, nicht 'list' als Variablennamen zu verwenden, da die eingebaute Funktion' list() ' – jamylak

+0

yeap du hast Recht, ich habe gerade den Code schnell bearbeitet, mein ursprünglicher Code sieht nicht so aus. – Oz123

Antwort

27
>>> l = ['a', 'b', 'c', 'd', 'e', 'f'] 
>>> zip(*[iter(l)]*2) 
[('a', 'b'), ('c', 'd'), ('e', 'f')] 

Wie es von @Lattyware darauf hingewiesen wurde, funktioniert dies nur, wenn es genügend Elemente in jedem Argument der zip Funktion jedes Mal, wenn ein Tupel zurück. Wenn einer der Parameter weniger Elemente als die anderen hat, werden Elemente abgeschnitten, z.

>>> l = ['a', 'b', 'c', 'd', 'e', 'f','g'] 
>>> zip(*[iter(l)]*2) 
[('a', 'b'), ('c', 'd'), ('e', 'f')] 

Wenn dies der Fall ist, dann ist es am besten, um die Lösung von @Sven Marnach verwenden

How does zip(*[iter(s)]*n) work

+3

Diese Lösung funktioniert nur, wenn genügend Gegenstände zum Ausfüllen vorhanden sind, da sonst Gegenstände abgeschnitten werden. –

+0

Erstellen eines Generators und Duplizieren eines Verweises darauf; klug. –

+1

@NickT technisch gut ist es ein Iterator kein Generator und ich kann nicht für die Klugheit Kredit nehmen :) – jamylak

11

Diese in der Regel das Grouper Rezept aus dem itertools documentation erfolgt über:

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return itertools.izip_longest(fillvalue=fillvalue, *args) 

Beispiel:

>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 
>>> list(grouper(2, my_list)) 
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', None)] 
0

Wenn man eine Liste von Listen, anstatt eine Liste von Tupeln aus einer flachen Liste zieht, dann könnte man dies tun:

a = range(20) # sample starting list 
    b = [] # new list 
    c = [] # alternate new list 
    # ny is length of new list. nx length of each list within it 
    nx = 5; ny = 4 
    bb = 0; ee = bb + nx # option one: sliding indeces for slices. 
    for ii in range(ny-1): 
     bb += nx 
     ee += nx 
     b.append(a[bb:ee]) 
     c.append(a[slice(ii*nx,nx*(ii+1))]) # option two, use slice() 

(Ich habe gespielt um mit dem ganzen for-Schleife in eine Linie schrumpfen mit Listenergänzungen, aber waren nicht erfolgreich. So wie ich es benutzt habe, kann Slice() Sie fast dorthin bringen.) Ein möglicher Vorteil dieser Ansätze gegenüber den anderen genannten ist, dass wenn Ihre ursprüngliche, flache Liste nicht ein gerades Vielfaches der Dimensionen Ihres neuen, gewünschten ist Liste von Listen, verlieren Sie keine Daten. Der Vorbehalt ist, dass die letzte Liste kürzer sein wird als alle anderen, da sie die "Überbleibsel" enthalten wird. Zugegeben, keine dieser Methoden scheint mir sehr pythisch.

Verfahren jede Zeile und Spalte Größe herzustellen erweitert werden kann Dies kann
>>>MyList = ['a','b','c','d','e','f'] 
# Calculate desired row/col 
>>>row = 3 
>>>col = 2 
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] 
>>>NewList 
[['a', 'b', 'c'], ['d', 'e', 'f']] 

:

+0

Ich verstehe nicht, warum Sie 'slice()' in der zweiten Methode verwenden, anstatt die Slice-Syntax. Eine Berechnung zu machen bedeutet nicht, dass Sie nicht 'a [ii * nx: nx * (ii + 1)]' oder was auch immer verwenden können. – Blckknght

5

andere Möglichkeit, eine Liste von Listen erstellen kann, wie unten gezeigt vereinfacht werden. Wenn Sie Zeilen- und Spaltenwerte wählen, dass row*col >len(MyList), die Unterliste (Zeile) beendet den letzten Wert in MyList enthält, wird dort, und NewList wird einfach mit der entsprechenden Anzahl von leeren Listen gefüllt werden, um die Zeile/Spalte-Spezifikationen zu erfüllen

>>>MyList = ['a','b','c','d','e','f','g','h'] 
>>>row = 3 
>>>col = 3 
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] 
>>>NewList 
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g','h']] 

>>>row = 4 
>>>col = 4 
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] 
[['a', 'b', 'c', 'd'], ['e', 'f', 'g','h'], [], []] 
+1

Ich denke, das sollte die akzeptierte Antwort sein, da die Frage nach einer Liste von Listen und nicht nach einer Liste von Tupeln verlangte. Oder die Antwort von Robert im obigen Kommentar. –

Verwandte Themen