#python #regex #permutation
Вопрос:
Я хотел перечислить все возможные ассоциативные операции для группы из n элементов. Например, когда n=3, я хочу, чтобы он печатался:
a*(a*a) = (a*a)*a
a*(a*b) = (a*a)*b
a*(a*c) = (a*a)*c
... 24 more lines
Теперь моя лучшая попытка создать их-это следующий код python3.
import itertools as it
def permutation_func(str_, rep):
chars = list(str_)
results = []
for tuple_ in it.product(chars, repeat = rep):
i = ''.join(tuple_)
results.append(i)
return results
my_list = permutation_func('abc', 3)
for i in my_list:
print(i, " = ", i)
Однако результат, который я получаю, таков:
aaa = aaa
aab = aab
aac = aac
... and 24 more lines
Я думаю, что я на правильном пути. Но я не могу понять, как преобразовать aaa = aaa
, в a*(a*a) = (a*a)*a
которое в основном мне нужно вставить *
знак и круглые скобки несколько раз внутри текста.
Я попробовал погуглить и обнаружил, что для этого мне нужны регулярные выражения. Однако я никогда не использовал регулярное выражение. Поэтому я ищу альтернативу, которая не использует регулярное выражение. Я даже не знаю, возможно ли это без регулярного выражения. Если это не так, дайте мне знать, пожалуйста.
Комментарии:
1. Пожалуйста, добавьте несколько примеров для n=4 или более? Я полагаю, что скобки в этих случаях могут быть в нескольких наборах, например
(a * b * c) * d
, или(a * b) * (c * d)
илиa * (b * c) * d
илиa * (b * c * d)
, и все они равны.2. Привет @AKS ваш вопрос больше похож на вопрос по алгебре. В любом случае, я боюсь, что вы ошиблись. Для n=4 первые 3 строки будут такими же, как n=3, но четвертая строка будет a* (a * d) =(a * a) * d. Здесь это двоичная операция, и ассоциативность двоичной операции определяется следующим образом. Например, ваш (a b c) не имеет никакого смысла, если это не тринарный оператор, и это ваша нотация, чтобы выразить так. В противном случае разница между n=3 и n=4 заключалась бы в том, что в n=4 было бы 64 строки, а не 27.
3. Я понимаю, так можно ли с уверенностью сказать , что независимо от того, сколько элементов в строке, скажем
abc
, илиabcd
, вы всегда генерируете перестановку из 3 символов?4. Да, именно так. Вот что такое ассоциативность!
Ответ №1:
К сожалению, строки в Python не являются изменяемыми объектами, поэтому вы просто можете вставить символ в позицию. (И регулярные выражения не помогли бы — у них есть причудливый механизм для замены некоторого текста, и , хотя можно было бы выполнять нужные вставки с помощью вызова re.sub
, выяснять правильное регулярное выражение и функцию обратного вызова для этого не стоило бы)
С другой стороны, s Python list
-это последовательности, которые могут быть произвольно изменены. И, к счастью, существует простой механизм преобразования строк в списки и обратно. Как только у вас появится список, вы можете либо использовать .insert
метод, либо срезать назначение, чтобы вставить свои значения:
a = "aaa"
b = list(a)
b.insert(1, "*")
b.insert(2, "(")
b.insert(4, "*")
b.insert(6,")")
c = "".join(b)
Учитывая то, что вы собираетесь делать, возможно, это не самый практичный способ сделать это — у вас, вероятно, должна быть функция, которая будет получать последовательность токенов в качестве входных данных (которая может быть списком или строкой с однобуквенными токенами), а также инструкции о том, как группировать и интерполировать символ, а затем возвращать его в виде строки:
def group_tokens(tokens, start, end, join="*"):
output = ""
for index, token in enumerate(tokens):
if index != 0:
output = join
if index == start:
output = "("
elif index == end:
output = ")"
output = token
if end >= len(tokens):
output = ")"
return output
Комментарии:
1. Функция group_tokens () — это то, что я точно хотел. Я использовал его в конце своего кода, и это решило мою проблему. Этот бит кода даже помог мне получить более общий вывод для n=4 и более. Спасибо.
2.
my_list = permutation_func('abc', 3) for i in my_list: i1 = group_tokens(i,1,3) i2 = group_tokens(i,0,2) i2 = i2.replace("*)",")*") print(i1, " = ", i2)
Это то, что дает точное решение
Ответ №2:
Основываясь на комментариях, должно сработать следующее
for c1, c2, c3 in itertools.product('abc', repeat=3):
print(f'({c1}*{c2})*{c3} = {c1}*({c2}*{c3})')
Он печатает:
(a*a)*a = a*(a*a)
(a*a)*b = a*(a*b)
(a*a)*c = a*(a*c)
... 24 more
Если вы замените строку на abcd
, она сгенерирует 64 записи.