Python 3.5 - 创建使用生成器填充的命名元组

时间:2016-05-08 01:16:46

标签: python iterator generator list-comprehension namedtuple

尝试压缩我的代码并且对Python很新,所以如果有一个前一个主题涵盖了我想要的内容,我会道歉。我尝试过搜索和阅读很多,但收效甚微。非常感谢任何帮助,谢谢!

(请假设单元格调用来自某个随机电子表格,其中包含我所需的数据。)

import xlrd
import collections

L_col = (21, 0, 27, 24, 3, 4, 11, 35, 18, 26)
L_label = ('Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating', 'Ventilation', 'People', 'Volume')
sp = collections.namedtuple('Space', ['Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating',
                                      'Ventilation', 'People', 'Volume'])

a = (L_ws.cell_value(row, L_col[0]) for row in range(start, end))
b = (L_ws.cell_value(row, L_col[1]) for row in range(start, end))
c = (L_ws.cell_value(row, L_col[2]) for row in range(start, end))
d = (L_ws.cell_value(row, L_col[3]) for row in range(start, end))
e = (L_ws.cell_value(row, L_col[4]) for row in range(start, end))
f = (L_ws.cell_value(row, L_col[5]) for row in range(start, end))
g = (L_ws.cell_value(row, L_col[6]) for row in range(start, end))
h = (L_ws.cell_value(row, L_col[7]) for row in range(start, end))
i = (L_ws.cell_value(row, L_col[8]) for row in range(start, end))
j = (L_ws.cell_value(row, L_col[9]) for row in range(start, end))

rs = sp(a, b, c, d, e, f, g, h, i, j)

2 个答案:

答案 0 :(得分:2)

在我看来,你可以做到:

items = [
    [L_ws.cell_value(row, L_col[i]) for row in range(start, end)]
    for i in range(10)]
rs = sp(*items)

如果您需要在物品中安装发电机,我建议您使用发电机功能:

def gen_item(column_number):
    for row_number in range(start, end):
        yield L_ws.cell_value(row_number, L_col[column_number])

rs = sp(*(gen_item(i) for i in range(10)))

此生成器假定通过闭包获取startendL_col。如果您愿意,可以将它们作为参数传递。

此外,您还有一些重复:

L_label = ('Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating', 'Ventilation', 'People', 'Volume')
sp = collections.namedtuple('Space', ['Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating',
                                      'Ventilation', 'People', 'Volume'])

可能只是:

L_label = ('Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating', 'Ventilation', 'People', 'Volume')
sp = collections.namedtuple('Space', L_label)

有了这样的说法......将生成器表达式放入命名元组中感觉有点奇怪(尽管无法 )...

答案 1 :(得分:0)

您可以执行以下操作:

import xlrd
import collections

def create_gen(column, start, end):
    return (L_ws.cell_value(row, column) for row in range(start, end))

L_col = (21, 0, 27, 24, 3, 4, 11, 35, 18, 26)
L_label = ('Room_ID', 'Name', 'Type', 'Area', 'Sens_Cooling', 'Lat_Cooling', 'Heating', 'Ventilation', 'People', 'Volume')
sp = collections.namedtuple('Space', L_label)
rs = sp(*(create_gen(col, start, end) for col in L_col))

由于您已在L_label中拥有字段名称,因此可以将其传递给namedtuple,而不是创建其他列表。

对于生成器,您可以编写生成器表达式,迭代L_col中的列。对于每一列,生成器表达式都会调用一个单独的方法,该方法返回一个与之前创建的生成器类似请注意,您需要在此处使用closure,因为在调用生成器时会评估col。最后,在传递给*之前,使用sp运算符解压缩结果。