2016-08-24 11 views
3

Ich möchte eine Append-akkumulierte Liste aus einer bestimmten Liste (oder Iterator) generieren oder zurückgeben. Für eine Liste wie [1, 2, 3, 4] möchte ich gerne [1], [1, 2], [1, 2, 3] und [1, 2, 3, 4] bekommen. Wie so:Liste Accumulation mit Append

>>> def my_accumulate(iterable): 
...  grow = [] 
...  for each in iterable: 
...   grow.append(each) 
...   yield grow 
... 
>>> for x in my_accumulate(some_list): 
...  print x # or something more useful 
... 
[1] 
[1, 2] 
[1, 2, 3] 
[1, 2, 3, 4] 

Das funktioniert aber gibt es eine Operation ich mit itertools.accumulate verwenden könnte dies zu erleichtern? (Ich bin auf Python2 aber die pure-Python-Implementierung/Äquivalent ist in der Dokumentation zur Verfügung gestellt.)

Ein weiteres Problem, das ich mit my_accumulate ist, dass es nicht gut mit list() nicht funktioniert, gibt es die gesamte some_list für jeden Element in der Liste:

>>> my_accumulate(some_list) 
<generator object my_accumulate at 0x0000000002EC3A68> 
>>> list(my_accumulate(some_list)) 
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] 

Option 1:

schrieb ich meine eigene Anfügen Speicher-Funktion mit itertools.accumulate zu verwenden, aber der LoC und letzter nützlicher Heit unter Berücksichtigung i t scheint wie eine Verschwendung von Aufwand, mit my_accumulate nützlicher sein, (wenn auch bei leerem Iterables fehlschlagen und mehr Speicher verbraucht, da grow wächst):

>>> def app_acc(first, second): 
...  if isinstance(first, list): 
...  first.append(second) 
...  else: 
...  first = [first, second] 
...  return first 
... 
>>> for x in accumulate(some_list, app_acc): 
...  print x 
... 
1 
[1, 2] 
[1, 2, 3] 
[1, 2, 3, 4] 
>>> list(accumulate(some_list, app_acc)) # same problem again with list 
[1, [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] 

(und das erste zurück Elem ist keine Liste, nur ein einzelnes Element)


Option 2: Dachte es wäre nur inkrementelle Slicing tun sich leichter, aber die hässliche Iterierte über Listenlänge Methode:

Antwort

8

Der einfachste Weg, accumulate zu verwenden ist jedes Element in der iterable einer Liste mit einem einzigen Punkt zu machen und dann der Standardfunktion wie erwartet funktioniert:

from itertools import accumulate 
acc = accumulate([el] for el in range(1, 5)) 
res = list(acc) 
# [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]] 
+1

Und Sie können Klammern um den Generator Ausdruck entfernen für zusätzliche Schönheit: 'akkumulieren ([el] für el im Bereich (1, 5))' – vaultah

+1

@vaultah yup ... Ich hatte ursprünglich, weil ich operator.add als Funktionsargument verwendet hatte und dann erkannte, dass es redundant war und gerade passiert zu vergessen, sie zu entfernen: p –

+1

Ja, das ist genial, denn für Listen 'operator.add' (' + ') tut' [1] + [2] = [1, 2] ',' [1 , 2] + [3] = [1, 2, 3] 'und so weiter. Vielen Dank! – aneroid

Verwandte Themen