Python 使用列表理解创建子列表

Python 使用列表理解创建子列表,python,python-3.x,Python,Python 3.x,我正在读取一些.csv文件,并将每列附加到不同的列表中 .csv文件示例: 工作Python代码 lst_a=[] lst_b=[] 使用opencsv_文件,“r”作为f_读取: csv_reader=csv.readerf_read,分隔符=',' 对于csv_读取器中的行: 第一行[0] 第一行[1] printlst_a[0,2,4] printlst_b[1,3,5] 我想使用列表理解而不是for循环来加快速度,因为我正在阅读数百万个.csv文件。然而,到目前为止还没有成功。我可以得到

我正在读取一些.csv文件,并将每列附加到不同的列表中

.csv文件示例: 工作Python代码 lst_a=[] lst_b=[] 使用opencsv_文件,“r”作为f_读取: csv_reader=csv.readerf_read,分隔符=',' 对于csv_读取器中的行: 第一行[0] 第一行[1] printlst_a[0,2,4] printlst_b[1,3,5]
我想使用列表理解而不是for循环来加快速度,因为我正在阅读数百万个.csv文件。然而,到目前为止还没有成功。我可以得到一个列表列表,但这不是我想要的:csv_file_list=[[floati for I in row]for row in csv_reader]

这不是很好的实践,也不是很好的python代码,但是:

[(lst_a.append(float(row[0])), lst_b.append(float(row[1]))) for row in csv_reader] 
工作。不建议这样做的原因是,您正在创建一个没有副作用的列表,而列表理解的设计目的是具有简单的输出功能,并且在理解中没有副作用。之所以执行“append”代码,是因为python解释器尝试计算列表,即使不需要该列表。这是创建for循环的目的!当然,选择权在你

编辑:使用zip既美观又简洁:

lst_a, lst_b = [[float(i) for i in x] for x in zip(*csv_reader)]
但这并不完美。这是因为zip将在csv的行上迭代n次,其中n是列数,而没有zip的for循环或列表理解则不会。因此,如果你有一个100万行和10列的csv,这将大大降低你的速度。

只需使用zip!它将压缩所有第一元素,所有第二元素

>>> with open(csv_file, 'r') as f_read:
...     csv_reader = csv.reader(f_read, delimiter = ',')
...     print(list(zip(*csv_reader)))
... 
[('0', '2', '4'), ('1', '3', '5')]
*csv_reader-星形是列表解包=我们将列表中的元素作为单独的参数传递。这使得它将所有子列表视为zip的输入列表


zip的结果是一个zip对象—一个在迭代时生成的生成器,因此我必须使用list来打印结果。

您可以使用zip和一次通过读取器来实现这一点:

lst_a,lst_b = map(list,zip(*(map(float,row) for row in csvReader)))

你反对像熊猫一样使用图书馆吗?是的,它非常慢。看一看,如果你正在读取数百万个文件,那么速度会很慢,尤其是在python中。你可能需要考虑你的设计,你真的需要这两个大的列表,或者你可以在迭代过程中处理这些数据吗?@拉斐尔,有趣的是,根据TimeIT,只要CSV文件有足够的行,熊猫就比你当前的代码做得更好。当您的csv文件有3行时,您的代码工作得更好,但一旦我将csv扩展到~5k行,一个简单的pandas实现的速度大约是原来的两倍。根据timeit@Chris_Rands我需要在两个500行的列表中执行一些计算。我只使用了一个json文件,但开始出现内存问题。然后我把所有的文件都保存在一个hdf5文件中,速度非常慢,所以我一直使用5M个.csv文件。如果没有其他方法,我将保留for循环。正如建议的那样,我能看到的唯一方法是使用zip。lst_a,lst_b=*[[floati for i in x]for x in zip*csv_reader]您的代码中有一个额外的*,如果没有它,它工作得很好,但是与for循环相比,性能没有提高,可能是因为zip。修复了这个问题,谢谢。是的,这就是我不建议使用zip的原因,对于一个有数百万行的文件,zip必须在创建列表之前读取每一行,因此它应该比我最初的答案慢,这是基于对行的一次迭代。实际上,zip有大约500行的数百万个文件。我接受了答案,因为它符合要求。谢谢你抽出时间,谢谢。工作正常,但由于map+zip,速度较慢。
lst_a,lst_b = map(list,zip(*(map(float,row) for row in csvReader)))