无法使用嵌套 for 循环比较 Python 中的 2 excel 工作表
Trouble comparing 2 excel sheets in Python using nested for loop
使用 python 3.4,我在处理一个较大程序的一小部分时遇到问题。对于这部分,我需要比较两个 excel sheets 'Bookings.xlsx' 和 'Forced.xlsx'.
的 A 列
A 列包含两个 sheet 中的预订编号,bookings.xlsx 包含 forced.xlsx
中每个预订编号所需的数据(在同一行中)
这是我遇到问题的部分。
reloc_sheet = reloc_book.sheet_by_index(0)
forced_sheet = forced_book.sheet_by_index(0)
bookings_sheet = bookings_book.sheet_by_index(0)
forced_rentals = []
for force_row in range(4,forced_sheet.nrows): #row 0:3 are headers
Fnum = forced_sheet.cell(force_row, 0)
for book_row in range(1,bookings_sheet.nrows): #row 0 is a header
Bnum = bookings_sheet.cell(book_row,0)
if Fnum == Bnum:
booNum = str(bookings_sheet.cell(book_row,0))
renCODate = bookings_sheet.cell(book_row,2)
renCOLoc = str(bookings_sheet.cell(book_row,4))
renUnit = str(bookings_sheet.cell(book_row,13))
renAgent = str(bookings_sheet.cell(book_row,12))
forced_rentals += [[booNum,renCODate,renCOLoc,renUnit,renAgent]]
据我了解,这应该查看 'forced' sheet(变量 Fnum)中的每个预订编号,并将其与 'bookings' sheet(变量 Bnum),当它找到匹配项时,它会将相应的数据从该行添加到列表 'forced_rentals'.
问题是此循环完成后,列表为空,但它应该找到 632 个匹配项,因此包含 632 个嵌套列表。我确定这是一个非常简单的解决方案,但我想不通。
将 cell()
更改为 cell_value()
,
Fnum = forced_sheet.cell_value(force_row, 0)
Bnum = bookings_sheet.cell_value(book_row,0)
或将 Fnum
和 Bnum
的类型转换为 str
将根据它们的内容字符串比较它们。
if str(Fnum) == str(Bnum):
注意 cell()
returns 一个 xlrd.sheet.Cell
对象。
xlrd 的 和 Cell
class 没有 __eq__()
和 __ne()__
支持相等运算符。在这里阅读更多:https://docs.python.org/2/reference/datamodel.html#object.ne
你可以在这里查看 xlrd 的源代码,https://github.com/python-excel/xlrd/blob/master/xlrd/sheet.py。
来自 The xlrd Module:
cell(rowx, colx) [#]
Cell object in the given row and column.
cell_value(rowx, colx) [#]
Value of the cell in the given row and column.
因此,Fnum
和 Bnum
的类型是 xlrd.sheet.Cell
,而不是 str
。
>>> type(Fnum)
<class 'xlrd.sheet.Cell'>
>>>
>>> type(Bnum)
<class 'xlrd.sheet.Cell'>
但是在使用cell_value()
,
>>> type(Fnum)
<class 'str'>
>>>
>>> type(Bnum)
<class 'str'>
然后你可以根据它们的字符串值来比较它们。
我的问题已经解决了。首先是现在有效的代码片段:
forced_rentals = []
for force_row in range(4,forced_sheet.nrows):
Fnum = forced_sheet.cell_value(force_row, 0)
Fnum_type = type(Fnum)
if type(Fnum) is float:
Fnum = str(Fnum)
Fnum = Fnum.replace('.0','')
if Fnum[-2:] == '/1':
Fnum = Fnum.replace('/1','')
for book_row in range(1,bookings_sheet.nrows):
Bnum = bookings_sheet.cell_value(book_row,0)
Bnum_type = type(Bnum)
if type(Bnum) is float:
Bnum = str(Bnum)
Bnum = Bnum.replace('.0','')
if Bnum[-2:] == '/1':
Bnum = Bnum.replace('/1','')
if Fnum == Bnum:
booNum = str(bookings_sheet.cell_value(book_row,0))
renCODate = bookings_sheet.cell_value(book_row,2)
renCOLoc = str(bookings_sheet.cell_value(book_row,4))
renUnit = str(bookings_sheet.cell_value(book_row,13))
renAgent = str(bookings_sheet.cell_value(book_row,12))
forced_rentals += [[booNum,renCODate,renCOLoc,renUnit,renAgent]]
break
1) 全数字 Bnum
或 Fnum
变量要么是字符串,例如 '7123456',要么是浮点数 7123456.0,它们未被识别为相同的值。转换为字符串只会使浮点数“7123456.0”再次不同。我通过以下方式解决了这个问题:
if type(Fnum) is float:
Fnum = str(Fnum)
Fnum = Fnum.replace('.0','')
这会将浮点数转换为字符串并删除“.0”
2) 当我意识到并非所有预订编号(Bnum
和 Fnum
变量)都会包含 /1 时,下一个问题出现了。 Rental 7123456 和 rental 7123456/1 相同,但我们的报告服务器(生成 excel sheets)将交替使用这两个,这意味着强制 sheet 可能有 7123456 和 booking sheet 有 7123456/1。为了弥补这一点,我添加了这个:
if Fnum[-2:] == '/1':
Fnum = Fnum.replace('/1','')
这将查找任何以“/1”结尾的预订编号并将其删除。
使用 python 3.4,我在处理一个较大程序的一小部分时遇到问题。对于这部分,我需要比较两个 excel sheets 'Bookings.xlsx' 和 'Forced.xlsx'.
的 A 列A 列包含两个 sheet 中的预订编号,bookings.xlsx 包含 forced.xlsx
中每个预订编号所需的数据(在同一行中)这是我遇到问题的部分。
reloc_sheet = reloc_book.sheet_by_index(0)
forced_sheet = forced_book.sheet_by_index(0)
bookings_sheet = bookings_book.sheet_by_index(0)
forced_rentals = []
for force_row in range(4,forced_sheet.nrows): #row 0:3 are headers
Fnum = forced_sheet.cell(force_row, 0)
for book_row in range(1,bookings_sheet.nrows): #row 0 is a header
Bnum = bookings_sheet.cell(book_row,0)
if Fnum == Bnum:
booNum = str(bookings_sheet.cell(book_row,0))
renCODate = bookings_sheet.cell(book_row,2)
renCOLoc = str(bookings_sheet.cell(book_row,4))
renUnit = str(bookings_sheet.cell(book_row,13))
renAgent = str(bookings_sheet.cell(book_row,12))
forced_rentals += [[booNum,renCODate,renCOLoc,renUnit,renAgent]]
据我了解,这应该查看 'forced' sheet(变量 Fnum)中的每个预订编号,并将其与 'bookings' sheet(变量 Bnum),当它找到匹配项时,它会将相应的数据从该行添加到列表 'forced_rentals'.
问题是此循环完成后,列表为空,但它应该找到 632 个匹配项,因此包含 632 个嵌套列表。我确定这是一个非常简单的解决方案,但我想不通。
将 cell()
更改为 cell_value()
,
Fnum = forced_sheet.cell_value(force_row, 0)
Bnum = bookings_sheet.cell_value(book_row,0)
或将 Fnum
和 Bnum
的类型转换为 str
将根据它们的内容字符串比较它们。
if str(Fnum) == str(Bnum):
注意 cell()
returns 一个 xlrd.sheet.Cell
对象。
和 Cell
class 没有 __eq__()
和 __ne()__
支持相等运算符。在这里阅读更多:https://docs.python.org/2/reference/datamodel.html#object.ne
你可以在这里查看 xlrd 的源代码,https://github.com/python-excel/xlrd/blob/master/xlrd/sheet.py。
来自 The xlrd Module:
cell(rowx, colx) [#]
Cell object in the given row and column.
cell_value(rowx, colx) [#]
Value of the cell in the given row and column.
因此,Fnum
和 Bnum
的类型是 xlrd.sheet.Cell
,而不是 str
。
>>> type(Fnum)
<class 'xlrd.sheet.Cell'>
>>>
>>> type(Bnum)
<class 'xlrd.sheet.Cell'>
但是在使用cell_value()
,
>>> type(Fnum)
<class 'str'>
>>>
>>> type(Bnum)
<class 'str'>
然后你可以根据它们的字符串值来比较它们。
我的问题已经解决了。首先是现在有效的代码片段:
forced_rentals = []
for force_row in range(4,forced_sheet.nrows):
Fnum = forced_sheet.cell_value(force_row, 0)
Fnum_type = type(Fnum)
if type(Fnum) is float:
Fnum = str(Fnum)
Fnum = Fnum.replace('.0','')
if Fnum[-2:] == '/1':
Fnum = Fnum.replace('/1','')
for book_row in range(1,bookings_sheet.nrows):
Bnum = bookings_sheet.cell_value(book_row,0)
Bnum_type = type(Bnum)
if type(Bnum) is float:
Bnum = str(Bnum)
Bnum = Bnum.replace('.0','')
if Bnum[-2:] == '/1':
Bnum = Bnum.replace('/1','')
if Fnum == Bnum:
booNum = str(bookings_sheet.cell_value(book_row,0))
renCODate = bookings_sheet.cell_value(book_row,2)
renCOLoc = str(bookings_sheet.cell_value(book_row,4))
renUnit = str(bookings_sheet.cell_value(book_row,13))
renAgent = str(bookings_sheet.cell_value(book_row,12))
forced_rentals += [[booNum,renCODate,renCOLoc,renUnit,renAgent]]
break
1) 全数字 Bnum
或 Fnum
变量要么是字符串,例如 '7123456',要么是浮点数 7123456.0,它们未被识别为相同的值。转换为字符串只会使浮点数“7123456.0”再次不同。我通过以下方式解决了这个问题:
if type(Fnum) is float:
Fnum = str(Fnum)
Fnum = Fnum.replace('.0','')
这会将浮点数转换为字符串并删除“.0”
2) 当我意识到并非所有预订编号(Bnum
和 Fnum
变量)都会包含 /1 时,下一个问题出现了。 Rental 7123456 和 rental 7123456/1 相同,但我们的报告服务器(生成 excel sheets)将交替使用这两个,这意味着强制 sheet 可能有 7123456 和 booking sheet 有 7123456/1。为了弥补这一点,我添加了这个:
if Fnum[-2:] == '/1':
Fnum = Fnum.replace('/1','')
这将查找任何以“/1”结尾的预订编号并将其删除。