[英]How to get all combinations of integers and operations across two lists?
我有两个清单:
ints = [10, 20, 30, 40, 50]
和
opers = ['+', '-', '*', '/']
我想获得一个包含这两个列表的所有可能组合的列表,例如:
10+20*40-30/50 = 810
50-40+30*20/10 = 70
等等
列表应为[810, 70, ...]
我相信此列表中应该总共有2880个元素。 如果int[0]==int[1]
,则为此将它们视为单独的。
我想我将不得不使用eval()
两个实际上获取列表中的元素。 我只是不知道如何以这种方式排列两个列表。 任何帮助将不胜感激。
谢谢
关键是使用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)}')
输出看起来像这样(很明显,您可以将其放在字典中或其他内容中):
...
50-10/30+40*20 = 849.6666666666666
50-10/30*40+20 = 56.66666666666667
50*10+30-40/20 = 528.0
50*10+30/40-20 = 480.75
50*10-30+40/20 = 472.0
50*10-30/40+20 = 519.25
50*10/30+40-20 = 36.66666666666667
50*10/30-40+20 = -3.333333333333332
50/10+30-40*20 = -765.0
50/10+30*40-20 = 1185.0
50/10-30+40*20 = 775.0
50/10-30*40+20 = -1175.0
50/10*30+40-20 = 170.0
50/10*30-40+20 = 130.0
50+10-40*20/30 = 33.33333333333333
...
创建所有排列,删除不适合的排列(数字运算...等)并计算:
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, ...]
有点解释:对于ints
和opers
两个给定排列:
(10, 30, 50, 20, 40)
('-', '*', '/', '+')
zip_longest
会给我们:(注意,由于opers
列表较短,缺少的值将由fillvalue填写''
)
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'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.