无法使用嵌套 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)

或将 FnumBnum 的类型转换为 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.

因此,FnumBnum 的类型是 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) 全数字 BnumFnum 变量要么是字符串,例如 '7123456',要么是浮点数 7123456.0,它们未被识别为相同的值。转换为字符串只会使浮点数“7123456.0”再次不同。我通过以下方式解决了这个问题:

if type(Fnum) is float:
                Fnum = str(Fnum)
                Fnum = Fnum.replace('.0','')

这会将浮点数转换为字符串并删除“.0”

2) 当我意识到并非所有预订编号(BnumFnum 变量)都会包含 /1 时,下一个问题出现了。 Rental 7123456 和 rental 7123456/1 相同,但我们的报告服务器(生成 excel sheets)将交替使用这两个,这意味着强制 sheet 可能有 7123456 和 booking sheet 有 7123456/1。为了弥补这一点,我添加了这个:

if Fnum[-2:] == '/1':
                Fnum = Fnum.replace('/1','')

这将查找任何以“/1”结尾的预订编号并将其删除。