Python:从任意大小的数据集创建大小相等的列表

时间:2016-11-14 23:23:15

标签: python list csv dictionary

我正在编写一个循环遍历.csv的小脚本,将文件中的每一行存储为字典,然后将该字典触发到一维列表中的API。

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)

request列表如下所示:

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

这个脚本可以工作,但是我循环遍历一个800万行的.csv,这个方法太慢了。我想通过每个API调用发送多行来加快此过程。我正在使用的API允许我每次调用最多发送100行。

如何更改此脚本以逐步构建包含100个词典的列表,将其发布到API然后重复。我将发送给此API的示例如下所示:

[
    {
        "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"
    }
]

一件不起作用的事情是构建一个庞大的列表然后将其分成大小为100的n个列表。原因是我的机器在任何给定时间都无法将所有数据保存在内存中。

2 个答案:

答案 0 :(得分:1)

您可以创建一个请求列表,只要其大小足够大,就可以将其发送到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 = []

然后,您只需要注意,您还要为最后一个非完整列表调用API。可以通过在循环后使用剩余列表调用API来完成,或者CSV阅读器可以告诉您它是否是最后一行。

答案 1 :(得分:1)

可以使用range(100)except StopIteration:来执行此操作,但这不是很漂亮。相反,生成器非常适合从CSV文件中一次获取100行的块。因为它不会使你的实际迭代和请求逻辑混乱,所以它会产生相当优雅的代码。检查一下:

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)

然而,我并不完全确定你从哪里获得i_headers,但我认为你已经在实际代码中弄明白了。