python中的"reduce"函数不适用于"namedtuple"?

fea*_*thj 4 python reduce lambda

我有一个日志文件,格式如下:

datetimestring \t username \t transactionName \r\n
Run Code Online (Sandbox Code Playgroud)

我试图在这个数据集上运行一些统计数据.我有以下代码:

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
Run Code Online (Sandbox Code Playgroud)

我不想为这样一个简单的数据集定义一个类,所以我使用了一个名字元组.当我尝试运行时,我收到此错误:

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'
Run Code Online (Sandbox Code Playgroud)

似乎lambda函数直接在'transactionDate'属性上运行,而不是传入完整的元组.如果我将lambda更改为:

lambda x,y: min(x, y)
Run Code Online (Sandbox Code Playgroud)

它像我期望的那样工作.任何想法为什么会这样?

NPE*_*NPE 5

只需使用:

minDate = min(t.transactionDate for t in transactions)
Run Code Online (Sandbox Code Playgroud)

以下是您的代码无法正常工作的原因说明.

让我们说... 在transactions = [t1, t2, t3]哪里t1...... t3是三个命名元组.

通过定义reduce,您的代码:

reduce(lambda x,y: min(x.transactionDate, y.transactionDate), transactions)
Run Code Online (Sandbox Code Playgroud)

相当于

min(min(t1.transactionDate, t2.transactionDate).transactionDate, t3.transactionDate)
Run Code Online (Sandbox Code Playgroud)

显然,内部min()返回time.struct_time而不是命名元组,因此当reduce尝试应用.transactionDate它时,它会失败.

有办法解决这个问题,并利用reduce这个问题.然而,似乎没有什么意义,因为直接应用min工作和我的眼睛比任何涉及的事情都要清楚得多reduce.

  • 或`key = operator.attrgetter('transactionDate')`.当内置的东西做同样的事情时,不要使用`lambda`. (2认同)