2011-10-04 64 views
4

我有一個是通過以下方式格式化的日誌文件:在python中的「減少」功能不工作在「namedtuple」?

datetimestring \t username \t transactionName \r\n 

我試圖運行在該數據集的一些統計數據。我有以下代碼:

import time 
import collections 
file = open('Log.txt', 'r') 

TransactionData = collections.namedtuple('TransactionData', ['transactionDate', 'user', 'transactionName']) 
transactions = list() 

for line in file: 
    fields = line.split('\t') 

    transactionDate = time.strptime(fields[0], '%Y-%m-%d %H:%M:%S') 
    user = fields[1] 
    transactionName = fields[2] 

    transdata = TransactionData(transactionDate, user, transactionName) 
    transactions.append(transdata) 

file.close() 

minDate = reduce(lambda x,y: min(x.transactionDate, y.transactionDate), transactions) 
print minDate 

我不想定義一個類這樣一個簡單的數據集,所以我使用的名稱元組。當我嘗試運行,我得到這個錯誤:

Traceback (most recent call last): 
    File "inquiriesStat.py", line 20, in <module> 
    minDate = reduce(lambda x,y: min(x.transactionDate, y.transactionDate), transactions) 
    File "inquiriesStat.py", line 20, in <lambda> 
    minDate = reduce(lambda x,y: min(x.transactionDate, y.transactionDate), transactions) 
AttributeError: 'time.struct_time' object has no attribute 'transactionDate' 

看來,lambda函數是在「transactionDate」性質而工作,而不是直接傳遞完整的元組。如果我將lambda更改爲:

lambda x,y: min(x, y) 

它按我的預期工作。任何想法,爲什麼會是這種情況?

+0

我相信一個沒有'reduce'的世界...... – JBernardo

回答

5

只需使用:

minDate = min(t.transactionDate for t in transactions) 

下面就是爲什麼你的代碼是不工作的說明。

比方說transactions = [t1, t2, t3]其中t1 ... t3是三個命名元組。

通過的reduce的定義,你的代碼:

reduce(lambda x,y: min(x.transactionDate, y.transactionDate), transactions) 

相當於

min(min(t1.transactionDate, t2.transactionDate).transactionDate, t3.transactionDate) 

顯然,內min()回報time.struct_time,而不是一個名爲元組,所以當reduce嘗試應用.transactionDate對它來說,那失敗了。

有辦法解決這個問題,並利用reduce來解決這個問題。然而,min直接應用這個工作似乎沒有什麼意義,我的眼睛比涉及reduce的任何東西都清晰得多。

+2

或'key = operator.attrgetter('transactionDate')'。當有內置功能執行相同操作時,不要使用'lambda'。 – agf

+1

reduce不起作用,因爲要減少的第一個調用(time.struct_time)的結果作爲下一個調用的參數之一傳入。 – Duncan

+1

@agf:爲什麼在效率或者實際上使'operator.attrgetter'更好? –