I have the following table:
+----------------+---------+------------+
| Cambridge Data | IRR | Price List |
+================+=========+============+
| '3/31/1989' | '4.37%' | |
+----------------+---------+------------+
| '4/30/1989' | '5.35%' | |
+----------------+---------+------------+
I want to convert the table and populate a Price List of 100
when the date in Cambridge Data is '4/30/1989'. I have the following function using 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
Here's an example using a similar method from petl's documentation:
>>> # 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 |
+-----+-------+--------------------+
There are three major problems with your function.
First, you're trying to assign a value to v
. But assignments are statements, not expressions. You can't put statements inside expressions in Python, and lambda
is an expression. But you can always just use def
instead:
def func(v, row):
v = '100' if row['Cambridge Parser'] == '3/31/1989'
table = etl.convert(table, 'Price List', func, pass_row=True)
Second, '100' if row['Cambridge Parser'] == '3/31/1989'
is not a valid expression in Python. if
statements may not require else
, but if
expressions do. So, it would have to look more like this:
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)
… or:
def func(v, row):
if row['Cambridge Parser'] == '3/31/1989':
v = '100'
table = etl.convert(table, 'Price List', func, pass_row=True)
Finally, even after you fix that, assigning a value to v
doesn't do any good anyway. v
is just the name of the parameter to your function. Rebinding that name to some other value is pointless; once you exit the function, that parameter no longer exists. In particular, it won't have any effect on whatever value was passed into the function.
If you look at the example function, it doesn't try to assign anything, it just returns the new value. Which is what you want to do here. So, either:
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)
… or, if you want to make it as concise as possible even if that means you don't understand your own code:
table = etl.convert(table, 'Price List', lambda v, row: '100' if row['Cambridge Parser'] == '3/31/1989' else v, pass_row=True)