Python 如何在两个列表中获得整数和运算的所有组合?
我有两份清单:Python 如何在两个列表中获得整数和运算的所有组合?,python,python-3.x,permutation,Python,Python 3.x,Permutation,我有两份清单: ints = [10, 20, 30, 40, 50] 及 我想获得一份包含这两份清单所有可能组合的清单,例如: 10+20*40-30/50 = 810 50-40+30*20/10 = 70 等等 然后列表应该是[810,70,…] 我相信这个列表中应该有2880个元素。如果int[0]==int[1],它们将被视为单独的 我想我必须使用eval()two实际获取列表中的元素。我就是想不出如何以这种方式排列这两个列表。任何帮助都将不胜感激 谢谢关键是使用itertool
ints = [10, 20, 30, 40, 50]
及
我想获得一份包含这两份清单所有可能组合的清单,例如:
10+20*40-30/50 = 810
50-40+30*20/10 = 70
等等
然后列表应该是[810,70,…]
我相信这个列表中应该有2880个元素。如果int[0]==int[1]
,它们将被视为单独的
我想我必须使用eval()
two实际获取列表中的元素。我就是想不出如何以这种方式排列这两个列表。任何帮助都将不胜感激
谢谢关键是使用
itertools.permutations
功能。这是一种天真的方式:
import itertools
ints = [10, 20, 30, 40, 50]
opers = ['+', '-', '*', '/']
for i in itertools.permutations(ints):
for o in itertools.permutations(opers):
s = f'{i[0]}{o[0]}{i[1]}{o[1]}{i[2]}{o[2]}{i[3]}{o[3]}{i[4]}'
print(f'{s} = {eval(s)}')
输出如下所示(显然,您可以将其放在字典或任何东西中):
创建所有排列,删除不适合的排列(编号操作…等),并计算:
from itertools import permutations
ints = ['10', '20', '30', '40', '50']
opers = [ '+', '-', '*', '/']
perm = permutations(ints+opers)
# sets for faster lookup
i = set(ints)
ops = set(opers)
fil = (p for p in perm
if all(p[k] in i if k%2==0 else p[k] in ops
for k in range(len(p))))
calcMe = [''.join(f) for f in fil]
calcMe = [''.join(f) for f in fil]
for cal in calcMe:
print(f"{cal}={eval(cal)}")
print(len(calcMe))
输出:
10+20-30*40/50=6.0
10+20-30*50/40=-7.5
10+20-30/40*50=-7.5
10+20-30/50*40=6.0
10+20-40*30/50=6.0
10+20-40*50/30=-36.66666666666667
10+20-40/30*50=-36.66666666666666
10+20-40/50*30=6.0
有更多的排列,然后需要和'评估'本身被认为是“危险的”,如果不加思考的应用。在这种情况下,它应该是好的,尽管我对输入有完全的控制权
from itertools import permutations, zip_longest, chain
def all_combinations(ints, ops):
for i in permutations(ints):
for o in permutations(ops):
yield "".join(filter(bool(chain.from_iterable(zip_longest(i, o)))))
有点神秘的最后一行执行以下操作:
对于给定的整数和运算符排列,压缩它们(缺少的值为
None
)。将这些拉链对连在一起,形成一种“梳理”操作。filter(bool,…)
调用会删除None
,这取决于您的喜好,您可能会选择其他方式。最后,str.join
将整数运算符序列转换为字符串。您可以使用一些itertools创建如下列表:
from itertools import permutations, chain, zip_longest
ints = [10, 20, 30, 40, 50]
opers = ['+', '-', '*', '/']
output = []
for int_perm in permutations(ints):
for op_perm in permutations(opers):
calculation = ''.join(map(str, chain.from_iterable(zip_longest(int_perm, op_perm, fillvalue=''))))
output.append(eval(calculation))
print(len(output))
# 2880
print(output)
# [6.0, -7.5, 609.2, -25.0, -1989.3333333333333, ...]
一点解释:对于两个给定的int
和opers
排列:
(10, 30, 50, 20, 40)
('-', '*', '/', '+')
zip\u longest
将为我们提供:(注意,由于opers
列表较短,缺少的值将由fillvalue''
填充)
链接此列表中的元组将为我们提供:
print(list(chain.from_iterable(zip_longest(int_perm, op_perm, fillvalue=''))))
# [10, '-', 30, '*', 50, '/', 20, '+', 40, '']
我们只需将所有项目映射到字符串,并将它们连接起来即可获得:
# '10-30*50/20+40'
我想组合的数量将是2880。我肯定在itertools
中可能有一些东西。有人知道吗?或者对乘积(置换(ints,5),置换(opers,4))中的(d1,d2,d1,d2,o2,o3,o4)求值这有点低效。为什么要查找所有排列,然后进行筛选?为什么不只是两个置换的产物?@FHTMitchell没有你的解决方案那么聪明,我同意。你在python 2上吗50+20-10*40/30在Python3(这个问题被标记为)上不是一个整数。我不认为我的更聪明——如果我认为这是一个试图做得太多而没有收获的话。
print(list((zip_longest(int_perm, op_perm, fillvalue=''))))
# [(10, '-'), (30, '*'), (50, '/'), (20, '+'), (40, '')]
print(list(chain.from_iterable(zip_longest(int_perm, op_perm, fillvalue=''))))
# [10, '-', 30, '*', 50, '/', 20, '+', 40, '']
# '10-30*50/20+40'