Идиома для «сокращения» списка другим списком методов

#python #reduce #idioms

#python #уменьшить #идиомы

Вопрос:

Я столкнулся с ситуацией, когда я хотел «уменьшить» один список целых чисел другим списком методов.

 >>> import operator
>>> 
>>> OPS = [operator.add, operator.sub, operator.add]
>>> nums = [1,2,3,4]
>>> 
>>> OPS[2](OPS[1](OPS[0](nums[0],nums[1]),nums[2]),nums[3])
4
  

для цикла:

 >>> result = nums[0]
>>> for i in range(1,len(nums)):
...     result = OPS[i-1](result,nums[i])
... 
>>> print result
4
  

«очереди»:

 >>> result = nums.pop(0)
>>> while nums:
...     result = OPS.pop(0)(result, nums.pop(0))
... 
>>> print result
4
  

Если бы я просто хотел применить один метод к списку чисел, например operator.add , я мог бы использовать reduce .

 >>> reduce(operator.add, [1,2,3,4])
10
  

Есть ли что-то подобное для объединения двух списков, одного из операторов и другого из операндов?

Ответ №1:

Нет.

 >>> OPS = [operator.add, operator.sub, operator.add]
>>> nums = [1, 2, 3, 4]
>>> print reduce(lambda x, y: y[0](x, y[1]), zip(OPS, nums[1:]), nums[0])
4
  

Ответ №2:

Аналогично решению Игнасио, но с итераторами и izip, и только для Python < 3.x:

 >>> import operator
>>> import itertools
>>> 
>>> ops = [operator.add, operator.sub, operator.add]
>>> nums = iter([1, 2, 3, 4])
>>> 
>>> print reduce(lambda a, (f, b): f(a, b), itertools.izip(ops, nums), next(nums))
4
  

Ответ №3:

 >>> it = iter(OPS)
>>> reduce(lambda *a: next(it)(*a), nums)
4