2016-12-20 1 views
2

Ich habe Tausende von IDs extrahiert aus einer CSV-Datei (jetzt ist es ein Generator von IDs), um diese IDs zu iterieren und zu verarbeiten.Vermeiden Sie Generator-Splitter, um keine Werte zu erzeugen

Um den Code zu optimieren, habe ich diese IDs in den Batches gruppiert und eine ganze Charge gleichzeitig verarbeitet.

Folgende Code Partition-ate den Generator in der Losgröße von n.

from itertools import zip_longest 
def grouper(n, iterable): 
    """ Grouping of iterable with n objects 
     Attributes 
     :n No. of values in a group 
     :iterable/string to be iterated 
     :return group of string/iterator values 
    "grouper(3, 'abcdefg') --> ('a','b','c'), ('d','e','f'), ('g',None, None)" 
    """ 
    return zip_longest(*[iter(iterable)]*n) 

zB:

>>>acc_ids = ['ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47', 'ID54', 'ID58'] 
#--As an iterator 
>>>id_generator = (i for i in acc_ids) 
>>>batches = grouper(7, id_generator) 
>>>batches 
<itertools.zip_longest object at 0x7f3beb3313b8> 
#This iterator is much similar to the below list and notice padded `None`(s) at the end of last batch: 
#[('ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47'), ('ID54', 'ID58', None, None, None, None, None)] 

Hier ist das Problem, entfernen gepolsterte None Werte aus dem Iterator Ich verwende filter

for batch in batches: 
    batch = list(filter(None, batch)) 

Diese Filter None Werte aus der Liste zu entfernen . Da ich denke, statt was einen zusätzlichen Filter, können wir verhindern, dass die Herstellung gepolsterte None Werte während des Generators Aufspalten ...

Abfragen:

  • Gibt es einen anderen Ansatz großen Generator zu spalten zu produzieren Chargen ohne None/Null-Werte am Ende der letzten Charge hinzufügen.
    ODER
  • Können wir über die Funktion grouper ändern, um gefüllte None-Werte zu unterdrücken?
+1

* "Aber dieser Filter gibt mir eine Liste zurück" *, in Python 3 gibt es keine Liste zurück, ein 'filter' Objekt wird zurückgegeben. –

+0

Textdateien von 'filter' in Python 3" Gib einen Iterator zurück, der diese iterierbaren Elemente ergibt ... " –

+0

@ JimFasarakis-Hilliard: Entschuldigung, dass ich das in eine Liste umwandeln möchte, um einen HTTP-API-Aufruf auszulösen, werde ich aktualisieren die Frage, die ich nur gepolsterte keine Werte entfernen möchte.und müssen Filter vermeiden –

Antwort

3

Dies könnte für Sie arbeiten:

def grouper(n, iterable): 
    iter_ = iter(iterbale) 
    while True: 
     res = tuple(next(iter_) for _ in range(n)) 
     if not res: 
      return 
     yield res 


acc_ids = ['ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47', 'ID54', 'ID58'] 
id_generator = iter(acc_ids) 
batches = grouper(7, id_generator) 
print(list(batches)) 

Ausgang:

[('ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47'), ('ID54', 'ID58')] 
+0

Funktioniert das für Sie? –

+0

Anstelle von 'raise StopIteration' wäre es besser zurückzukehren (yeah, gib einfach nichts zurück). Die 'raise StopIteration' ist aus (wahrscheinlich guten) Gründen veraltet. – MSeifert

+0

@MSeifert Ja, sieht ein bisschen schöner aus. Geändert. Vielen Dank. –

1

Eine Möglichkeit ist eine externe Bibliothek zu verwenden, die bereits eine solche Funktion beinhaltet:

  • iteration_utilities.grouper:

    >>> from iteration_utilities import grouper 
    >>> list(grouper(acc_ids, 7)) 
    [('ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47'), ('ID54', 'ID58')] 
    
  • more-itertools.chunked:

    >>> from more_itertools import chunked 
    >>> list(chunked(acc_ids, 7)) 
    [['ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47'], ['ID54', 'ID58']] 
    
  • pytoolz.partition_all oder cytoolz.partition_all:

    >>> from toolz import partition_all 
    >>> list(partition_all(7, acc_ids)) 
    [('ID21', 'ID24', 'ID38', 'ID40', 'ID42', 'ID43', 'ID47'), ('ID54', 'ID58')] 
    

Diese Bibliotheken haben alle liberalen Lizenzen (Apache, MIT und BSD) so, auch wenn Sie don‘ Ich möchte die Abhängigkeit, die Sie möglicherweise nur ihren Code wiederverwenden (Sie müssen möglicherweise ihre Lizenz in Ihrem c enthalten Ode, siehe ihre Lizenzen für weitere Details).

Verwandte Themen