Python 解析表时处理 NoneType
Python handling NoneType when parsing tables
我正在尝试比较两个 table(table_a
和 table_b
)并从 [=17= 的最后一列中减去 table_a
的最后一列].但是,table_a 包含一个额外的行并导致我收到 NoneType
错误。有没有办法我仍然可以包含 table_a
中的“Plums”行并只为增量单元格输出 NULL
?下面是我的测试table代码。
当前代码:
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)))
错误输出:
------------------------------------------------------------
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
Traceback (most recent call last):
File "/media/test.py", line 30, in <module>
q = b[4]
TypeError: 'NoneType' object is not subscriptable
如果我添加一个 if 语句来删除 NoneType,它会打印 table 而不会出现错误,但会排除“Plums”行。
for a, b in itertools.zip_longest(table_a, table_b):
if a and b is not None:
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
itertools.zip_longest
接受可选的 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')]
您可以提供空行(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):
...
zip_longest returns 单数 None
类型,当它用完值时。当您尝试使用下标 []
运算符时,您想要一个 None
的列表,或者您得到一个 TypeError
。
使用可选的 fillvalue 获取 None
的列表,然后在格式化输出时测试 None
,这样当您尝试时就不会得到另一个 TypeError
当 q
为 None
:
时执行 p-q
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'))
我正在尝试比较两个 table(table_a
和 table_b
)并从 [=17= 的最后一列中减去 table_a
的最后一列].但是,table_a 包含一个额外的行并导致我收到 NoneType
错误。有没有办法我仍然可以包含 table_a
中的“Plums”行并只为增量单元格输出 NULL
?下面是我的测试table代码。
当前代码:
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)))
错误输出:
------------------------------------------------------------
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
Traceback (most recent call last):
File "/media/test.py", line 30, in <module>
q = b[4]
TypeError: 'NoneType' object is not subscriptable
如果我添加一个 if 语句来删除 NoneType,它会打印 table 而不会出现错误,但会排除“Plums”行。
for a, b in itertools.zip_longest(table_a, table_b):
if a and b is not None:
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
itertools.zip_longest
接受可选的 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')]
您可以提供空行(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):
...
zip_longest returns 单数 None
类型,当它用完值时。当您尝试使用下标 []
运算符时,您想要一个 None
的列表,或者您得到一个 TypeError
。
使用可选的 fillvalue 获取 None
的列表,然后在格式化输出时测试 None
,这样当您尝试时就不会得到另一个 TypeError
当 q
为 None
:
p-q
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'))