此代码返回电子表格范围中的小部件列表,该小部件具有另一个范围,表明它已启用处理。代码可以正常运行,但实施起来很差,特别是在正确使用zip和布局方面。
我非常确定zip
和ws.iter_cols
应该是答案的一部分,而不是使用它们的最佳方式。唯一重要的一行是Row/column code
评论下的列表理解。那么,应该怎么做呢?
代码需要在各种范围上运行,但最初是硬编码用于开发。在openpyxl行/列处理比坐标范围更有效,并且坐标范围功能逐渐被折旧。 (坐标代码仅用于开发,将被删除。)
PEP8正在发出continuation line under-indented for visual indent
警告。
from __future__ import print_function
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
import openpyxl
def do_widgets(ws, col0, col1):
""" Process each widget. """
NO_WDGTS = 5
ENABLE_START_ROW = 6
ENABLE_END_ROW = ENABLE_START_ROW + NO_WDGTS - 1
WDGT_START_ROW = 1
WDGT_END_ROW = WDGT_START_ROW + NO_WDGTS - 1
# Coordinate code - delete whole block before implementation
col_letter0 = get_column_letter(col0)
col_letter1 = get_column_letter(col1)
wdgos_range = [(col_letter0 + str(ENABLE_START_ROW) + ":" +
col_letter0 + str(ENABLE_END_ROW))]
wdgos_range.append(col_letter1 + str(WDGT_START_ROW) + ":" +
col_letter1 + str(WDGT_END_ROW))
# Delete
# wdgos = [cell[1][0].value for cell in zip(ws['B6:B10'], ws['C1:C5'])
# if cell[0][0].value]
wdgos = [cell[1][0].value for cell in zip(ws[wdgos_range[0]], ws[wdgos_range[1]])
if cell[0][0].value]
# Row/column code
wdgts = [cell[1] for cell in zip([cell.value for col
in ws.iter_cols(min_row=ENABLE_START_ROW, min_col=col0,
max_row=ENABLE_END_ROW, max_col=col0)
for cell in col],
[cell.value for col
in ws.iter_cols(min_row=WDGT_START_ROW, min_col=col1,
max_row=WDGT_END_ROW, max_col=col1)
for cell in col]) if cell[0]]
# Use list of enabled widgets
print("Enable range [0], Widget range [1]")
print(wdgos_range)
for wdgo in wdgos:
print(wdgo)
print()
print(wdgts, '\n')
wb = Workbook()
ws = wb.active
rows = [
['Number', 'Batch 1', 'Batch 2'],
[2, 40, 30],
[3, 40, 25],
[4, 50, 30],
[5, 30, 10],
[0, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 1],
[0, 1, 0],
]
for row in rows:
ws.append(row)
# Worksheet, enable column, widget column
do_widgets(ws, 2, 3)
调试输出:
Enable range [0], Widget range [1]
['B6:B10', 'C1:C5']
30
25
10
[30, 25, 10]
答案 0 :(得分:1)
也许你可以简化一下如下:
#define cell "extractor" from given position
def get_cells(row, col):
for col in ws.iter_cols(min_row = row, min_col = col, max_row = row + NO_WDGTS - 1, max_col = col):
for cell in col:
yield cell.value
#use itertools.izip to zip the generators in order to process
#the elements one by one instead of generating them all at once
wdgts = [cell[1] for cell in itertools.izip(
get_cells(ENABLE_START_ROW, col0),
get_cells(WDGT_START_ROW, col1)) if cell[0]]