2016-11-14 3 views
0

Ich schreibe ein kleines Skript, das eine CSV-Schleife durchläuft, jede Zeile in der Datei als Wörterbuch speichert und dieses Wörterbuch an eine API in einer .sv sendet 1-dimensionale Liste.Python: Erstellen Sie Listen gleicher Größe aus einer Datei mit beliebiger Größe

import csv 
import requests 

with open('csv.csv', 'rU') as f: 
    reader = csv.reader(f, skipinitialspace=True) 
    header = next(reader) 
    for row in reader: 
     request = [dict(zip(header, map(str, row)))] 
     r = requests.post(url, headers = i_headers, json = request) 
     print str(reader.line_num) + "-" + str(r) 

Die request Liste sieht wie folgt aus etwas:

[ 
    { 
     "id": "1", 
     "col_1": "A", 
     "col_2": "B", 
     "col_3": "C" 
    } 
] 

Dieses Skript funktioniert, aber ich bin Looping durch eine 8.000.000 Reihe .csv, und diese Methode ist einfach zu langsam. Ich möchte diesen Prozess beschleunigen, indem ich mehr als eine Zeile pro API-Aufruf sende. Mit der API, mit der ich arbeite, kann ich bis zu 100 Zeilen pro Anruf senden.

Wie kann ich dieses Skript ändern, um inkrementell Listen mit 100 Wörterbüchern zu erstellen, diese an die API zu senden und dann zu wiederholen. Eine Probe von dem, was ich zu diesem API aussenden würde, würde so aussehen:

[ 
    { 
     "id": "1", 
     "col_1": "A", 
     "col_2": "B", 
     "col_3": "C" 
    }, 
    { 
     "id": "2", 
     "col_1": "A", 
     "col_2": "B", 
     "col_3": "C" 
    }, 
... 
... 
... 
    { 
     "id": "100", 
     "col_1": "A", 
     "col_2": "B", 
     "col_3": "C" 
    } 
] 

Eine Sache, die nicht funktionieren wird eine massive Liste zu erstellen und es dann in n Listen der Größe partitionieren 100. Der Grund weil meine Maschine nicht alle diese Daten zu einem bestimmten Zeitpunkt im Speicher halten kann.

+0

Partitionierung der Liste –

Antwort

1

Es ist möglich, dies mit range(100) und except StopIteration: zu tun, aber es ist nicht sehr hübsch. Stattdessen ist ein Generator perfekt, um Chunks von 100 Zeilen gleichzeitig aus Ihrer CSV-Datei zu erhalten. Da es Ihre aktuelle Iterations- und Anforderungslogik nicht überlagert, macht es ziemlich eleganten Code. Check it:

import csv 
import requests 
from itertools import islice 

def chunks(iterator, size): 
    iterator = iter(iterator) 
    chunk = tuple(islice(iterator, size)) 
    while chunk: 
     yield chunk 
     chunk = tuple(islice(iterator, size)) 

with open('csv.csv', 'rU') as f: 
    reader = csv.reader(f, skipinitialspace=True) 
    header = next(reader) 
    for rows in chunks(reader, 100): 
     rows = [dict(zip(header, map(str, row))) for row in rows] 
     r = requests.post(url, headers=i_headers, json=rows) 
     print str(reader.line_num) + "-" + str(r) 

Ich bin nicht ganz sicher, wo Sie bekommen i_headers aus, aber, aber ich nehme an, Sie habe die in Ihrer tatsächlichen Code herausgefunden.

1

Sie können eine Liste von Anforderungen erstellen, und immer dann, wenn seine Größe groß genug ist, schicken Sie es an die API:

import csv 
import requests 

with open('csv.csv', 'rU') as f: 
    reader = csv.reader(f, skipinitialspace=True) 
    header = next(reader) 
    requestList = [] 
    for row in reader: 
     requestList.append(dict(zip(header, map(str, row)))) 
     if len(requestList) >= 100: 
      r = requests.post(url, headers = i_headers, json = requestList) 
      print str(reader.line_num) + "-" + str(r) 
      requestList = [] 

Dann müssen Sie nur darauf achten, dass Sie auch für die API-Aufruf letzte, nicht vollständige Liste. Dies kann entweder durch Aufruf der API mit der verbleibenden Liste nach der Schleife erfolgen, oder der CSV-Reader kann Ihnen sagen, ob es sich um die letzte Zeile handelt.

+0

Danke! das hat perfekt funktioniert. – sumojelly

+0

Danke! Sie könnten diese Antwort als Lösung für Ihr Problem markieren. –

Verwandte Themen