循环遍历列表然后在python中使用双循环的更有效方法

时间:2014-08-22 23:10:15

标签: python loops for-loop

我有一个数据集,其格式为我想要循环的dicts列表,并根据与另一个值列表中的值的匹配来提取该数据集的子集。

我目前正在以两个单独的for x in y循环的方式执行此操作,如下面的示例代码所示,但我确信这是非常低效的并且它需要非常高效长时间查看大型列表。

CSV格式的示例数据:

╔══════════════╦══════════════╦═══════════════╦════════════════╦══════════════════════╗
║     City     ║    State     ║ 2013 Estimate ║ 2013 Land Area ║ 2013 Popular Density ║
╠══════════════╬══════════════╬═══════════════╬════════════════╬══════════════════════╣
║ New York     ║ New York     ║ 8405837       ║ 302.6 sq mi    ║ 27012 per sq mi      ║
║ Los Angeles  ║ California   ║ 3884307       ║ 468.7 sq mi    ║ 8092 per sq mi       ║
║ Chicago      ║ Illinois     ║ 2718782       ║ 227.6 sq mi    ║ 11842 per sq mi      ║
║ Houston      ║ Texas        ║ 2195914       ║ 599.6 sq mi    ║ 3501 per sq mi       ║
║ Philadelphia ║ Pennsylvania ║ 1,553,165     ║ 134.1 sq mi    ║ 11379 per sq mi      ║
║ Phoenix      ║ Arizona      ║ 1513367       ║ 516.7 sq mi    ║ 2798 per sq mi       ║
║ San Antonio  ║ Texas        ║ 1409019       ║ 460.9 sq mi    ║ 2880 per sq mi       ║
║ San Diego    ║ California   ║ 1355896       ║ 325.2 sq mi    ║ 4020 per sq mi       ║
║ Dallas       ║ Texas        ║ 1257676       ║ 340.5 sq mi    ║ 3518 per sq mi       ║
║ San Jose     ║ California   ║ 998537        ║ 176.5 sq mi    ║ 5359 per sq mi       ║
╚══════════════╩══════════════╩═══════════════╩════════════════╩══════════════════════╝

示例代码

#read data into list of dicts
import csv 
with open('data.csv', 'rb') as csv_file:
    data = list(csv.DictReader(csv_file))

# cities of interest to extract from larger data
int_cities = [['New York'],['Houston'],['Pheonix'],['San Jose']]

# loop through data and look for match in data['City'] and interest_cities, append match to int_cities_data
int_cities_data = []
for i in data:
    for u in int_cities:
        if i['City'] == u:
            int_cities_data.append(i)

正如我所说,这当前有效,但是当我必须在data中遍历~2M行并查看int_cities中另外50k行的匹配时,需要很长时间。

如何提高效率?

编辑2014-08-22美国东部时间晚上9:30

我忘了数据太大而无法使用csv.DictReader所以我一直使用以下内容将我的数据读入一个dicts列表(删除标题后):

这是未经测试的

header = ['City','State','2013 Estimate','2013 Land Area','2013 Popular Density']
data = [{key: value for (key, value) in zip(header, line.strip().split(','))} for line in open('data.csv') if line['City'] in int_cities]

我尝试修改上面的代码,用于将数据加载到dicts列表中,而不使用csv.DictReader

1 个答案:

答案 0 :(得分:4)

不是将文件中的所有数据都读入列表,而是遍历该列表以搜索所需的城市,一次迭代csv文件一行,并且只有在项目列表中才添加项目。重新关注你关心的城市。这样你就不需要将整个文件存储在内存中了,你不需要迭代两次(一次构建完整的列表,然后再次将你关心的条目拉出来)。

此外,请将您关注的城市存储在set而不是list,这样您就可以在O(1)时间而不是O(n)进行查找。如果你进行大量的查找(这听起来像你),这可能会大大提高性能。

#read data into list of dicts
import csv 

int_cities = set(['New York', 'Houston', 'Phoenix', 'San Jose'])
int_cities_data = []
with open('data.csv', 'rb') as csv_file:
    for line in csv.DictReader(csv_file):
        if line['City'] in int_cities:
            int_cities_data.append(line)

或者作为列表理解:

with open('data.csv', 'rb') as csv_file:
    int_cities_data = [line for line in csv.DictReader(csv_file) if line['City'] in int_cities]