2016-09-30 84 views
1

我想比較兩個表(table_a和table_b)並從table_b的最後一列中減去table_a的最後一列。但是,table_a包含一個額外的行,並導致我得到一個NoneType錯誤。是否有一個我可以仍然包括table_a的「李子」行,只是輸出爲零增量單元「NULL」?以下是我的可測試代碼。Python在解析表時處理NoneType

目前代碼:

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它打印該表沒有一個錯誤,但不包括 「李子」 行。

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))) 

輸出與如果聲明:

------------------------------------------------------------ 
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    

我想有下面的輸出。這裏的「梅子」行仍然打印,但有字符串「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   
+0

這是[pandas'](http://pandas.pydata.org/)軟件包的完美應用程序。一探究竟。 –

回答

2

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): 
    ... 
+0

首先感謝您的期待。該片段確實解決了NoneType錯誤,但表格仍未打印。現在我得到錯誤'TypeError:不支持的操作數類型爲 - :'int'和'str''。 – MBasith

+0

@MBasith,您可能需要使用另一個值,而不是可以在'-'操作中使用的「NULL」。我會更新答案。 – falsetru

+0

好的,我明白了。不能用字符串減去和整數。 – MBasith

1

zip_longest返回單數None類型,當它用完值。當您嘗試使用下標[]運算符時,您需要列表None或您得到TypeError

使用可選的fillvalue當你格式化輸出,所以你沒有得到另一TypeError當你嘗試做p-q得到NoneNone秒的列表,然後測試時qNone

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')) 
+0

@dawg此解決方案簡短而又甜美。工作很好。謝謝! – MBasith