这个使用 petl 的 lambda 函数有什么问题?
What's wrong with this lambda function using petl?
我有以下 table:
+----------------+---------+------------+
| Cambridge Data | IRR | Price List |
+================+=========+============+
| '3/31/1989' | '4.37%' | |
+----------------+---------+------------+
| '4/30/1989' | '5.35%' | |
+----------------+---------+------------+
当剑桥数据中的日期为“1989 年 4 月 30 日”时,我想转换 table 并填充 100
的价目表。我使用 petl 有以下功能:
# Add an initial price to base calculations for Price List
def insert_initial_price(self, table):
table = etl.convert(table, 'Price List', lambda v, row: v = '100' if row['Cambridge Parser'] == '3/31/1989', pass_row=True)
return table
下面是一个使用 petl 文档中类似方法的示例:
>>> # conversion can access other values from the same row
... table12 = etl.convert(table1, 'baz',
... lambda v, row: v * float(row.bar),
... pass_row=True)
>>> table12
+-----+-------+--------------------+
| foo | bar | baz |
+=====+=======+====================+
| 'A' | '2.4' | 28.799999999999997 |
+-----+-------+--------------------+
| 'B' | '5.7' | 193.8 |
+-----+-------+--------------------+
| 'C' | '1.2' | 67.2 |
+-----+-------+--------------------+
你的函数存在三个主要问题。
首先,您尝试为 v
赋值。但是赋值是语句,而不是表达式。在 Python 中不能将语句放在表达式中,而 lambda
是一个表达式。但是你总是可以只使用 def
来代替:
def func(v, row):
v = '100' if row['Cambridge Parser'] == '3/31/1989'
table = etl.convert(table, 'Price List', func, pass_row=True)
其次,'100' if row['Cambridge Parser'] == '3/31/1989'
不是 Python 中的有效表达式。 if
语句可能不需要 else
,但 if
表达式需要。所以,它必须看起来更像这样:
def func(v, row):
v = '100' if row['Cambridge Parser'] == '3/31/1989' else v
table = etl.convert(table, 'Price List', func, pass_row=True)
… 或:
def func(v, row):
if row['Cambridge Parser'] == '3/31/1989':
v = '100'
table = etl.convert(table, 'Price List', func, pass_row=True)
最后,即使在您修复该问题之后,为 v
赋值也无济于事。 v
只是函数的参数名称。将该名称重新绑定到其他值是没有意义的;退出该函数后,该参数将不再存在。特别是,它不会对传递给函数的任何值产生任何影响。
如果您查看示例函数,它不会尝试分配任何内容,它只是 returns 新值。这就是您想在这里做的。所以,要么:
def func(v, row):
if row['Cambridge Parser'] == '3/31/1989':
return '100'
else:
return v
table = etl.convert(table, 'Price List', func, pass_row=True)
…或者,如果你想让它尽可能简洁,即使这意味着你不理解你自己的代码:
table = etl.convert(table, 'Price List', lambda v, row: '100' if row['Cambridge Parser'] == '3/31/1989' else v, pass_row=True)
我有以下 table:
+----------------+---------+------------+
| Cambridge Data | IRR | Price List |
+================+=========+============+
| '3/31/1989' | '4.37%' | |
+----------------+---------+------------+
| '4/30/1989' | '5.35%' | |
+----------------+---------+------------+
当剑桥数据中的日期为“1989 年 4 月 30 日”时,我想转换 table 并填充 100
的价目表。我使用 petl 有以下功能:
# Add an initial price to base calculations for Price List
def insert_initial_price(self, table):
table = etl.convert(table, 'Price List', lambda v, row: v = '100' if row['Cambridge Parser'] == '3/31/1989', pass_row=True)
return table
下面是一个使用 petl 文档中类似方法的示例:
>>> # conversion can access other values from the same row
... table12 = etl.convert(table1, 'baz',
... lambda v, row: v * float(row.bar),
... pass_row=True)
>>> table12
+-----+-------+--------------------+
| foo | bar | baz |
+=====+=======+====================+
| 'A' | '2.4' | 28.799999999999997 |
+-----+-------+--------------------+
| 'B' | '5.7' | 193.8 |
+-----+-------+--------------------+
| 'C' | '1.2' | 67.2 |
+-----+-------+--------------------+
你的函数存在三个主要问题。
首先,您尝试为 v
赋值。但是赋值是语句,而不是表达式。在 Python 中不能将语句放在表达式中,而 lambda
是一个表达式。但是你总是可以只使用 def
来代替:
def func(v, row):
v = '100' if row['Cambridge Parser'] == '3/31/1989'
table = etl.convert(table, 'Price List', func, pass_row=True)
其次,'100' if row['Cambridge Parser'] == '3/31/1989'
不是 Python 中的有效表达式。 if
语句可能不需要 else
,但 if
表达式需要。所以,它必须看起来更像这样:
def func(v, row):
v = '100' if row['Cambridge Parser'] == '3/31/1989' else v
table = etl.convert(table, 'Price List', func, pass_row=True)
… 或:
def func(v, row):
if row['Cambridge Parser'] == '3/31/1989':
v = '100'
table = etl.convert(table, 'Price List', func, pass_row=True)
最后,即使在您修复该问题之后,为 v
赋值也无济于事。 v
只是函数的参数名称。将该名称重新绑定到其他值是没有意义的;退出该函数后,该参数将不再存在。特别是,它不会对传递给函数的任何值产生任何影响。
如果您查看示例函数,它不会尝试分配任何内容,它只是 returns 新值。这就是您想在这里做的。所以,要么:
def func(v, row):
if row['Cambridge Parser'] == '3/31/1989':
return '100'
else:
return v
table = etl.convert(table, 'Price List', func, pass_row=True)
…或者,如果你想让它尽可能简洁,即使这意味着你不理解你自己的代码:
table = etl.convert(table, 'Price List', lambda v, row: '100' if row['Cambridge Parser'] == '3/31/1989' else v, pass_row=True)