使用itertools.produ时使用名称引用参数

2024-05-15 05:42:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用python对大约8个参数的所有组合进行操作,评估每个组合对系统的影响

我想到了比8个嵌套的for循环更好的方法,并找到了itertools.product。这给出了一个更平坦的结构,但是引用product结果的好方法是什么?对于嵌套循环,组合中的每个参数都有一个方便的名称来引用它。使用itertools方法,我有一些代码来设置序列中参数的名称

示例(只有3个参数和糟糕的文件处理):

嵌套循环版本

import csv
import itertools

csv_writer = csv.writer(open('data.csv', 'wb'))
csv_writer.writerow(("x", "y", "bpp", "raw_size_bytes", "file_size_bytes"))

# 8bpp and below needs 1 byte per pixel, 9 to 16 bpp needs 2 bytes
file_bytes_per_pixel = [1]*9 + [2]*8

# iterate over parameter combination in nested "for"
for x in [640, 1024, 2048]:
    for y in [320, 1024, 1024]:
        for bpp in [8,10, 16]:
            raw_size_bytes = (x * y * bpp) / 8
            file_size_bytes = x * y * file_bytes_per_pixel[bpp]
            csv_writer.writerow((x, y, bpp, raw_size_bytes, file_size_bytes))

继续进入itertools版本

csv_writer = csv.writer(open('data2.csv', 'wb'))
csv_writer.writerow(("x", "y", "bpp", "raw_size_bytes", "file_size_bytes"))
range_x = [640, 1024, 2048]
range_y = [320, 1024, 1024]
range_bpp = [8,10, 16]

for x, y, bpp in itertools.product(range_x, range_y, range_bpp):
    raw_size_bytes = (x * y * bpp) / 8
    file_size_bytes = x * y * file_bytes_per_pixel[bpp]
    csv_writer.writerow((x, y, bpp, raw_size_bytes, file_size_bytes))

在itertools版本中,我将不同参数的含义重复了四次

  1. 写入csv文件标题
  2. 设置范围
  3. 将范围传递给product
  4. 为来自product的结果命名

用名称定义的索引

如果我给参数名赋值,可能会有一个改进:

csv_writer = csv.writer(open('data3.csv', 'wb'))

x, y, bpp = range(3)
params = range(3)

params[x] = [640, 1024, 2048]
params[y] = [320, 1024, 1024]
params[bpp] = [8, 10, 16]

csv_writer.writerow(("x", "y", "bpp", "raw_size_bytes", "file_size_bytes"))

for p in itertools.product(*params):
    raw_size_bytes = (p[x] * p[y] * p[bpp]) / 8
    file_size_bytes = p[x] * p[y] * file_bytes_per_pixel[p[bpp]]
    csv_writer.writerow((p[x], p[y], p[bpp], raw_size_bytes, file_size_bytes))

我觉得自己只重复了两次,但每次提到产品的结果时,我都有p[]

如果我在一个(有序的)字典中有参数,那么我可以使用.keys()来获取名称列表,使用.values()来获取product的范围。但是我不知道如何将product的结果转换成具有良好名称的变量来进行计算

在问这个问题的过程中,我觉得我已经找到了一种我相当满意的方法,但是是否有一种更干净的方法来使用产品,并且能够以一种合理的方式引用序列中返回的单个成员


Tags: csv方法infor参数sizerawbytes
2条回答

这让人感觉有点不舒服@sparklewhiskers但是您可以将这种方法应用到最后4行以减少重复的出现:)

out = ((x, y, bpp, x * y * bpp / 8, x * y * file_bytes_per_pixel[bpp]) for
        x, y, bpp in itertools.product(range_x, range_y, range_bpp))
csv_writer.writerow(out)

我不熟悉writerow,所以您可能需要输出列表而不是生成器

在问这个问题的过程中,我想我已经回答了,最简洁的方法似乎就是用“产品”和字典

csv_writer = csv.writer(open('data3.csv', 'wb'))

x, y, bpp = range(3)
params = range(3)

params[x] = [640, 1024, 2048]
params[y] = [320, 1024, 1024]
params[bpp] = [8, 10, 16]

csv_writer.writerow(("x", "y", "bpp", "raw_size_bytes", "file_size_bytes"))

for p in itertools.product(*params):
    raw_size_bytes = (p[x] * p[y] * p[bpp]) / 8
    file_size_bytes = p[x] * p[y] * file_bytes_per_pixel[p[bpp]]
    csv_writer.writerow((p[x], p[y], p[bpp], raw_size_bytes, file_size_bytes))

相关问题 更多 >

    热门问题