Как получить все комбинации целых чисел и операций в двух списках? - PullRequest
0 голосов
/ 28 августа 2018

У меня есть два списка:

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() два, чтобы получить элементы в списке. Я просто не могу понять, как переставить два списка таким образом. Любая помощь будет оценена.

Спасибо

Ответы [ 4 ]

0 голосов
/ 28 августа 2018

Вы можете создать список, например, используя 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 короче, пропущенное значение будет заполнено значением заполнения '')

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'
0 голосов
/ 28 августа 2018

Создайте все перестановки, удалите те, которые не подходят (число число операций ... и т. Д.) И рассчитайте:

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

Существует больше перестановок, чем необходимо, и «самооценка» сама по себе считается «опасной», если ее применять без мыслей. В этом случае все должно быть в порядке, хотя у меня есть полный контроль над входами.

0 голосов
/ 28 августа 2018
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 превращает последовательность целочисленных операторов в строку.

0 голосов
/ 28 августа 2018

Ключ должен использовать функцию 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
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...