Python在解析表时处理非类型

Python在解析表时处理非类型,python,python-3.x,parsing,itertools,nonetype,Python,Python 3.x,Parsing,Itertools,Nonetype,我试图比较两个表(表a和表b),并从表b的最后一列减去表a的最后一列。但是,表a包含一个额外的行,导致我得到一个NoneType错误。是否还有一种方法,我仍然可以包含表a中的“Plums”行,并只为delta单元格输出NULL?下面是我的可测试代码 当前代码: from datetime import datetime import itertools table_a = ( (datetime(2016, 9, 28, 0, 0), 'Apples', 650, 700, 850

我试图比较两个表(
表a
表b
),并从
表b
的最后一列减去
表a
的最后一列。但是,表a包含一个额外的行,导致我得到一个
NoneType
错误。是否还有一种方法,我仍然可以包含
表a
中的“Plums”行,并只为delta单元格输出
NULL
?下面是我的可测试代码

当前代码:

from datetime import datetime
import itertools

table_a = (
      (datetime(2016, 9, 28, 0, 0), 'Apples', 650, 700, 850),
      (datetime(2016, 9, 28, 0, 0), 'Oranges', 900, 950, 1000),
      (datetime(2016, 9, 28, 0, 0), 'Grapes', 1050, 1100, 1150),
      (datetime(2016, 9, 28, 0, 0), 'Plums', 2000, 3000, 4000)
      )

table_b = (
      (datetime(2016, 9, 27, 0, 0), 'Apples', 50, 150, 200),
      (datetime(2016, 9, 27, 0, 0), 'Oranges', 250, 350, 400),
      (datetime(2016, 9, 27, 0, 0), 'Grapes', 450, 550, 600),
      )

table_format = '{:<10}|{:<8}|{:<8}|{:<8}|{:<8}|{:<12}'
line_sep = ('-' * 60)

print(line_sep)
print(table_format.format('Date', 'Count_1', 'Count_2', 'Count_3' , 'Count_4', 'Count_4_Delta'))


for a, b in itertools.zip_longest(table_a, table_b):
      l = str(a[0])[0:10]
      m = a[1]
      n = a[2]
      o = a[3]
      p = a[4]
      q = b[4]
      print(line_sep)
      print(table_format.format(l, m, n, o, p, (p-q)))
使用If语句输出:

------------------------------------------------------------
Date      |Count_1 |Count_2 |Count_3 |Count_4 |Count_4_Delta
------------------------------------------------------------
2016-09-28|Apples  |650     |700     |850     |650         
------------------------------------------------------------
2016-09-28|Oranges |900     |950     |1000    |600         
------------------------------------------------------------
2016-09-28|Grapes  |1050    |1100    |1150    |550              
我想有下面的输出。其中“Plums”行仍在打印,但增量单元格的字符串为“NULL”

期望输出:

------------------------------------------------------------
Date      |Count_1 |Count_2 |Count_3 |Count_4 |Count_4_Delta
------------------------------------------------------------
2016-09-28|Apples  |650     |700     |850     |650         
------------------------------------------------------------
2016-09-28|Oranges |900     |950     |1000    |600         
------------------------------------------------------------
2016-09-28|Grapes  |1050    |1100    |1150    |550          
------------------------------------------------------------
2016-09-27|Plums   |2000    |3000    |4000    |NULL        
接受可选的
fillvalue
参数。如果提供了该参数,则使用该参数而不是
None

>>> list(itertools.zip_longest([1, 2, 3], [4, 5]))
[(1, 4), (2, 5), (3, None)]
>>> list(itertools.zip_longest([1, 2, 3], [4, 5], fillvalue='NULL'))
[(1, 4), (2, 5), (3, 'NULL')]
for a, b in itertools.zip_longest(table_a, table_b,fillvalue=[None]*5):
    l = str(a[0])[0:10]
    m = a[1]
    n = a[2]
    o = a[3]
    p = a[4]
    q = b[4]
    print(line_sep)
    print(table_format.format(l, m, n, o, p, (p-q) if q is not None else 'NULL'))
您可以提供空行(空值列表)作为
fillvalue

class EmptyValue:
    def __sub__(self, other):
        return 'NULL'
    def __rsub__(self, other):
        return 'NULL'

empty_row = [None, 'NULL', EmptyValue(), EmptyValue(), EmptyValue()]
for a, b in itertools.zip_longest(table_a, table_b, fillvalue=empty_row):
    ...
当值不足时返回单数
None
类型。您需要
None
s列表,或者在尝试使用下标
[]
运算符时得到
TypeError

使用可选的fillvalue获取
None
s列表,然后在格式化输出时测试
None
,这样当
q
None
时,尝试执行
p-q
时不会出现另一个
TypeError

>>> list(itertools.zip_longest([1, 2, 3], [4, 5]))
[(1, 4), (2, 5), (3, None)]
>>> list(itertools.zip_longest([1, 2, 3], [4, 5], fillvalue='NULL'))
[(1, 4), (2, 5), (3, 'NULL')]
for a, b in itertools.zip_longest(table_a, table_b,fillvalue=[None]*5):
    l = str(a[0])[0:10]
    m = a[1]
    n = a[2]
    o = a[3]
    p = a[4]
    q = b[4]
    print(line_sep)
    print(table_format.format(l, m, n, o, p, (p-q) if q is not None else 'NULL'))

首先感谢您的查看。该代码段确实解决了非类型错误,但表仍然没有打印。现在我得到错误“TypeError:不支持的操作数类型”对于-:'int'和'str'。@MBasith,您可能需要使用另一个值,而不是可以在
-
操作中使用的
'NULL'
。我将更新答案。好的,我明白了。不能用字符串进行减法和整数运算。这非常有效。我还不太熟悉类,但看起来它们非常有价值。如果您有时间的话你能告诉我这个类在做什么吗?非常感谢你的帮助。非常感谢。@MBasith,当你从
EmptyValue
实例中减去值时,会使用特殊的方法
\uuuu sub\uuu
\uuu rsub\uuu
当你从其他值减去
EmptyValue
实例时,会使用
方法。换句话说,
EmptyValue()-1
调用
EmptyValue()。\uuuu sub\uuuuuu(1)
1-EmptyValue()
调用
EmptyValue()。\uuuu rsub\uuuuuu(1)
(运算符重载)。我希望我的解释有意义。这是该软件包的完美应用程序。请查看。@dawg此解决方案短而甜美。效果很好。谢谢!