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

标签 python loops for-loop

我有一个字典列表格式的数据集,我想遍历它并根据与另一个值列表中的值的匹配提取该数据集的一个子集。

我目前通过两个单独的 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 行并查看 中的另外 50k 行是否存在匹配项时,这需要很长时间>int_cities

如何提高效率?

EDIT 2014-08-22 9:30 PM EST

我忘记了数据太大而无法使用 csv.DictReader 所以我一直在使用以下方法将我的数据读入字典列表(在删除标题之后):

这是未经测试的

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]

我试图修改上面的代码,我在不使用 csv.DictReader 的情况下将我的数据加载到字典列表中。

最佳答案

与其将文件中的所有数据读入列表,然后遍历该列表以搜索您想要的城市,不如一次一行地遍历 csv 文件,并且只在列表中添加项目重新为您关心的城市。这样您就不需要将整个文件存储在内存中,也不需要对其进行两次迭代(一次构建完整列表,然后再次从中提取您关心的条目)。

此外,将您关心的城市存储在集合中而不是列表中,因此您可以在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]

关于python - 循环遍历列表然后在 python 中使用双循环的更有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25456799/

相关文章:

python - 如何从屏幕上删除单个 pygame 绘图?

python - Python 中的应用程序配置文件

c - 初始化结构元素数组时出错

java - 为什么我不能以这种方式在 for 循环中定义变量?

c - 如何在 C 中找到数学表达式的第一个值(for 循环)

python - 防止Python线程饥饿

python - 使用 Python 获取 SharePoint 列表

C++ QuickSort算法不断崩溃

sql - 循环遍历sql server触发器中的数据

c# - 在循环语句中向文本文件添加新行