2016-09-11 4 views
0

я увидел следующий код для фильтрации списка на два класса:Как это работает функция фильтра + лямбда-списка?

reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49, 58, 76, 82, 88, 90],([],[])) 

Как это работает? ([], []) выглядит инициализацией (a, b) в лямбда, но как он работает шаг за шагом?

Это, похоже, не работает в Python 3. Почему?

ответ

0

Чтобы ответить на ваш первый запрос, эквивалент, используя цикл:

>>> c = [49, 58, 76, 82, 88, 90] 
>>> final = ([], []) 
>>> for val in c: 
...  if val > 60: 
...    final[0].append(val) 
...  else: 
...    final[1].append(val) 
... 
>>> final 
([76, 82, 88, 90], [49, 58]) 

Эквивалент в Python3 является:

In [8]: import functools 

In [9]: functools.reduce(lambda x,c: (x[0]+[c],x[1]) if c > 60 else (x[0],x[1] + [c]), [49, 58, 76, 82, 88, 90],([],[])) 
Out[9]: ([76, 82, 88, 90], [49, 58]) 
1

Как это работает? ([], []) выглядит инициализацией (a, b) в лямбда, но как он работает шаг за шагом?

В каждой точке, то уменьшают видит левый операнд руки, (a, b), который является парой списков (первоначально два пустых списков), и элемент c. Он добавляет список [c] либо a, либо b, в зависимости от того, является ли он больше 60 и возвращает новую пару списков. Таким образом, он в конечном итоге вернет пару элементов, превышающих 60, и меньше 60, соответственно.

Это, похоже, не работает в Python 3. Почему?

В Python3 вы уже не можете определить функцию, явно беря кортеж - tuple unpacking has been removed. Таким образом,

def foo((a, b)): 
    ... 

является незаконным в Python3. Это и проблема здесь (за исключением формы лямбда).

+0

Python3: уменьшить (lambda a, c: (a [0] + [c], a [1]), если c> 60 else (a [0], a [1] + [c ]), [49, 58, 76, 82, 88, 90], ([], [])) ' –

+0

@arvindpdmn Большое спасибо! –

0

Взгляните на следующий эксперимент:

>>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49],([],[])) 
([], [49]) 
>>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58],([],[])) 
([], [49, 58]) 
>>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76],([],[])) 
([76], [49, 58]) 
>>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76,82],([],[])) 
([76, 82], [49, 58]) 
>>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76,82,88,90],([],[])) 
([76, 82, 88, 90], [49, 58]) 

Функция reduce описывается следующим образом:

reduce(...) 
    reduce(function, sequence[, initial]) -> value 

    Apply a function of two arguments cumulatively to the items of a sequence, 
    from left to right, so as to reduce the sequence to a single value. 

В нашем примере функция является лямбда с первым аргументом в качестве 2-го элемента tuple (a,b) и второй аргумент как целое число c взято из списка для обработки. Поскольку функция создает 2-элементный набор списков, он инициализируется как ([], []). Когда начинается обработка, если элемент равен> 60, он добавляется в первый список кортежа; иначе он добавляется ко второму списку кортежей.

Синтаксис a+[c] - действительно синтаксис списка extend. Мы не можем сделать a+c, так как a - это список, а c - целое число. Аналогично, для b+[c]

 Смежные вопросы

  • Нет связанных вопросов^_^