2011-10-04 5 views
4

다음과 같은 형식으로 로그 파일이 있습니다.파이썬에서 "reduce"함수가 "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 

그런 간단한 데이터 셋을위한 클래스를 정의하고 싶지 않았다. 그래서 이름 튜플을 사용했다. 실행하려고하면이 오류가 발생합니다. xtx56

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' 

람다 함수가 전체 튜플을 전달하는 대신 직접 'transactionDate'속성에서 작동하는 것으로 보입니다. 람다를 다음과 같이 변경하면 :

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

감소시킬 첫 번째 호출 (time.struct_time)의 결과가 다음 호출의 인수 중 하나로 전달되므로 reduce가 작동하지 않습니다. – Duncan

+1

@agf : 효율성, 또는 실제로'operator.attrgetter'가 선호하는 이유가 있습니까? –

관련 문제