Что не так с этой лямбда-функцией, использующей petl? - PullRequest
0 голосов
/ 06 июня 2018

У меня есть следующая таблица:

+----------------+---------+------------+
| Cambridge Data | IRR     | Price List |
+================+=========+============+
| '3/31/1989'    | '4.37%' |            |
+----------------+---------+------------+
| '4/30/1989'    | '5.35%' |            |
+----------------+---------+------------+

Я хочу преобразовать таблицу и заполнить прайс-лист 100, если в данных Кембриджа указана дата «30.04.1989».У меня есть следующая функция, использующая 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 |
+-----+-------+--------------------+

1 Ответ

0 голосов
/ 06 июня 2018

У вашей функции три основные проблемы.

Сначала вы пытаетесь присвоить значение 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 - это просто имя параметра вашей функции.Связывать это имя с каким-либо другим значением бессмысленно;после выхода из функции этот параметр больше не существует.В частности, это не повлияет на то, какое значение было передано в функцию.

Если вы посмотрите на пример функции, она не пытается ничего присвоить, она просто возвращает новое значение.Что вы хотите сделать здесь.Итак, либо:

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)
...