使用索引列表访问项目列表

Posted

技术标签:

【中文标题】使用索引列表访问项目列表【英文标题】:Access list of items with list of indices 【发布时间】:2012-02-18 23:32:06 【问题描述】:

考虑从大型 csv 文件 (80 MB) 返回的大型命名项目列表(第一行),其中可能有中断的间距

name_line =  ['a',,'b',,'c' .... ,,'cb','cc']

我正在逐行读取剩余的数据,我只需要处理具有相应名称的数据。数据可能看起来像

data_line =  ['10',,'.5',,'10289' .... ,,'16.7','0']

我尝试了两种方法。一个是从读取的每一行中弹出空列

blnk_cols = [1,3, ... ,97]
while data:
    ...
    for index in blnk_cols: data_line.pop(index)

另一个正在编译与 L1 中的名称关联的项目

good_cols = [0,2,4, ... ,98,99]   
while data:
    ...
    data_line = [data_line[index] for index in good_cols]

在我使用的数据中,肯定会有更多的好行而不是坏行,尽管它可能高达一半。

我使用 cProfile 和 pstats 包来确定我最薄弱的速度链接,这表明 pop 是当前最慢的项目。我切换到列表组合,时间几乎翻了一番。

我想一种快速的方法是对数组进行切片,只检索好的数据,但这对于具有交替空白和好的数据的文件来说会很复杂。

我真正需要的是能够做到

data_line = data_line[good_cols]

有效地将索引列表传递到列表中以取回这些项目。 现在,对于一个 10 MB 的文件,我的程序在大约 2.3 秒内运行,而 pop 大约需要 0.3 秒。

是否有更快的方法来访问列表中的某些位置。在 C 中,它只是取消引用指向数组中正确索引的指针数组。

补充: 读取前文件中的 name_line

a,b,c,d,e,f,g,,,,,h,i,j,k,,,,l,m,n,

读取和拆分后的name_line(",")

['a','b','c','d','e','f','g','','','','','h','i','j','k','','','','l','m','n','\n']

【问题讨论】:

你在用 data_line 做什么?你只是在迭代它吗?您是否将其放入另一个数据结构中? 另外,你试过发电机吗? “考虑从一个大的 csv 文件返回一个大列表”?您是否将整个文件读入一个列表?为什么?为什么不单独处理每一行? 我正在阅读的文件是一个更高频率的文件(即10 hz)。我正在读取行并在 x 秒间隔内累积和平均所有值并将其写回文件中。即从 10 hz 到 1 hz 将累积 10 个数据值(从 0 到 1 秒)平均它们并将单个数据行输出到平均数据范围的地板(时间)的文件中 我正在单独处理每一行。为清楚起见进行了编辑 【参考方案1】:

尝试生成器表达式,

data_line = (data_line[i] for i in good_cols)

也在这里阅读 Generator Expressions vs. List Comprehension

正如最佳答案告诉您的那样:“基本上,如果您所做的只是迭代一次,请使用生成器表达式”。

所以你应该从中受益。

【讨论】:

哪个更快取决于你用它做什么。生成器的优点是它是惰性的,因此您不会为仅访问一次的项目分配大量内存。 @Marcin。是的,澄清了我的答案。 重构了我的所有代码以适应生成器表达式。我遍历每条数据线一次进行处理(使用具有适当索引的生成器,而不是最初弹出空白值)。代码运行慢了大约 0.3 秒,因为我需要为每个数据行重新创建生成器表达式。 @PaulSeeb 我很困惑。 创建生成器表达式不应该花费任何时间。 这个文件有 25000 行。我需要为每一行创建一个新的生成器来处理该行中的所有数据,除非我可以“重置”每一行的生成器。我对此进行了一些研究,发现这是不可能的。

以上是关于使用索引列表访问项目列表的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 列表理解中是不是可以访问项目索引?

如何在 Django 模板中使用变量索引访问列表?

循环中的 Django 计数器以索引列表

如何访问 *ngFor 中的“索引”并对其进行编辑(不能删除列表中的多个项目)

列表list

Python 列表list详解(超详细)