python - 用 2 个生成器替换 3 个列表

标签 python list optimization generator

我想使用生成器优化我的应用程序,而不是创建 3 个列表,我想使用 2 个生成器。这是我的应用程序当前版本的简短方案:

1) 从二进制文件加载数据 -> 第一个列表

self.stream_data = [ struct.unpack(">H", data_file.read(2))[0] for foo in
                       xrange(self.columns*self.rows) ]

2)创建所谓的非零抑制数据(所有数据都为零)->第二个列表

self.NZS_data = list()
for row in xrange(self.rows):
    self.NZS_data.append( [ self.stream_data[column + row * self.rows ] 
                          for column in xrange(self.columns) ] )

3) 创建零抑制数据(没有带坐标的零)-> 第三个列表

self.ZS_data = list()
for row in xrange(self.rows):
    for column in xrange(self.columns):
        if self.NZS_data[row][column]:
            self.ZS_data.append( [ column, row, self.NZS_data[row][column] ] )

(我知道这可以使用 itertools.product 压缩为单个列表理解)

4) 将ZS_data列表保存到文件中。

我使用Python的cProfiler,大部分时间(除了读取和解包)都用于创建这两个(NZS_data和ZS_data)列表。因为我只需要它们将数据保存到文件中,所以我一直在考虑使用 2 个生成器:

1) 创建一个用于读取文件的生成器 -> 第一个生成器

self.stream_data = ( struct.unpack(">H", data_file.read(2))[0] for foo in
                       xrange(self.columns*self.rows) )

2)创建 ZS_data 生成器(我真的不需要这个 NZS 数据)

self.ZS_data = ( [column, row, self.stream_data.next()]
                 for row, column in itertools.product(xrange(self.rows),
                 xrange(self.columns))
                 if self.stream_data.next() )

这当然无法正常工作,因为我从生成器获得了两个不同的值。

3)使用生成器将数据保存到文件中。

我想知道如何做到这一点。 也许您还有与此应用程序的可能优化相关的其他想法?

已添加
基于生成器的解决方案:

def create_ZS_data(self):
    self.ZS_data = ( [column, row, self.stream_data[column + row * self.rows ]]
                     for row, column in itertools.product(xrange(self.rows), xrange(self.columns))
                     if self.stream_data[column + row * self.rows ] )

分析器信息:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     3257    1.117    0.000   71.598    0.022 decode_from_merlin.py:302(create_ZS_file)
   463419   67.705    0.000   67.705    0.000 decode_from_merlin.py:86(<genexpr>)

乔恩的解决方案:

create_ZS_data(self):
    self.ZS_data = list()
    for rowno, cols in enumerate(self.stream_data[i:i+self.columns] for i in xrange(0, len(self.stream_data), self.columns)):
        for colno, col in enumerate(cols):
            # col == value, (rowno, colno) = index
            if col:
                self.ZS_data.append([colno, rowno, col])


探查器信息:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     3257   18.616    0.006   19.919    0.006 decode_from_merlin.py:83(create_ZS_data)

最佳答案

您可以使拆包更加高效...

self.data_stream = struct.unpack_from('>{}H'.format(self.rows*self.columns), data_file)

将循环减少为:

for rowno, cols in enumerate(self.data_stream[i:i+self.columns] for i in xrange(0, len(self.data_stream), self.columns)):
    for colno, col in enumerate(cols):
        # col == value, (rowno, colno) = index
        if col == 0:
            pass # do something
        else:
            pass # do something else

注意 - 未经测试

关于python - 用 2 个生成器替换 3 个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11602396/

相关文章:

python - Django:电子商务的产品变体

python - 列表子列表的优化

php - 定义简短的私有(private) PHP 嵌套函数(子函数)- 最佳性能?最佳实践?

python - 使用 execfile 时如何防止运行 __main__ 守卫?

python - 设置 AnchoredOffsetbox 的线宽和面颜色?

python - 如何在python中从csv绘制图形

python - 按 "column"的字母顺序对python中的列表列表进行排序

list - 在 f# 中处理列表的嵌套记录

java - 如何将 List<class> 放入 JSONObject 然后读取该对象?

c - 优化搜索最大平方算法中的函数