问题
第一步:给定一个数字列表,生成所有可能的分组(按顺序),只考虑所需最终组数。
例如,如果我的数字列表是 1 到 4,我想要最终分为 2 组,则可能性如下:
[1], [2,3,4]
[1,2], [3,4]
[1,2,3], [4]
步骤 2:对这些组进行算术运算。
例如,如果我们选择加法,则最终结果将为:
1 + 234 = 235
12 + 34 = 46
123 + 4 = 127
先前的研究和类似问题
我在 Stack Overflow 和其他地方看到了许多涉及不同数量组的变量的问题的例子,这些问题使用范围和 for 循环,例如:
print [num_list[i:i+groups] for i in range(0,len(num_list),groups)]
但这与我想要的相反 - 在那种情况下,除了最后一个组以外,各个组的长度都是固定的,而组数则会震荡。
这不是作业,只是我遇到的一个有趣的问题。理想情况下,我需要能够迭代这些单独的子列表以执行数学运算,因此它们也需要被捕获。
我有一种感觉解决方案将涉及到itertools,但我似乎无法弄清楚关于分组方面的组合数。
步骤2的编辑/扩展
如果我想对每个分区执行不同的操作,我还可以用同样的方法吗?而不仅仅是指定int.add,我是否可以以某种方式执行所有主要的4个运算的另一种组合?例如:
symbol_list = ['+','-','*','/']
for op in symbol_list:
#something
我最终会得到以下可能性:1 + 2 * 34
1 * 2 - 34
1 / 2 + 34
etc.
操作顺序可以忽略。
最终解决方案
#!/usr/bin/env python
import sys
from itertools import combinations, chain, product
# fixed vars
num_list = range(_,_) # the initial list
groups = _ # number of groups
target = _ # any target desired
op_dict = {'+': int.__add__, '-': int.__sub__,
'*': int.__mul__, '/': int.__div__}
def op_iter_reduce(ops, values):
op_iter = lambda a, (i, b): op_dict[ops[i]](a, b)
return reduce(op_iter, enumerate(values[1:]), values[0])
def split_list(data, n):
for splits in combinations(range(1, len(data)), n-1):
result = []
prev = None
for split in chain(splits, [None]):
result.append(data[prev:split])
prev = split
yield result
def list_to_int(data):
result = 0
for h, v in enumerate(reversed(data)):
result += 10**h * v
return result
def group_and_map(data, num_groups):
template = ['']*(num_groups*2 - 1) + ['=', '']
for groups in split_list(data, num_groups):
ints = map(list_to_int, groups)
template[:-2:2] = map(str, ints)
for ops in product('+-*/', repeat=num_groups-1):
template[1:-2:2] = ops
template[-1] = str(op_iter_reduce(ops, ints))
if op_iter_reduce(ops, ints) == target:
print ' '.join(template)
group_and_map(num_list, groups)
1 + 2 * 34
是否应该实际计算为(1 + 2) * 34
而不是正常的1 + (2 * 34)
)。 - Andrew Clark