Преобразование вложенного L oop в рекурсивную функцию в Python - PullRequest
0 голосов
/ 02 августа 2020

Здравствуйте, я напишу все состояние текста с верхним и нижним режимами один за другим, и я могу сделать это с помощью вложенного для , но это просто полезно для текста с 6 символами, я буду преобразовать его в Рекурсивный может кто-нибудь помочь?

text=['a','b','c','d','e','f']
for i in [0, 1]:
    if i == 1:
        text[0] = text[0].upper()
    else:
        text[0] = text[0].lower()
    for j in [0, 1]:
        if j == 1:
            text[1] = text[1].upper()
        else:
            text[1] = text[1].lower()
        for w in [0, 1]:
            if w == 1:
                text[2] = text[2].upper()
            else:
                text[2] = text[2].lower()
            for q in [0, 1]:
                if q == 1:
                    text[3] = text[3].upper()
                else:
                    text[3] = text[3].lower()
                for z in [0, 1]:
                    if z == 1:
                        text[4] = text[4].upper()
                    else:
                        text[4] = text[4].lower()
                    for g in [0, 1]:
                        if g == 1:
                            text[5] = text[5].upper()
                        else:
                            text[5] = text[5].lower()
                        print(''.join(text))

Результат находится ниже, а его Правильный , но я сделаю это с помощью Рекурсивный

ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF ABCDEF AbcdEf AbcdEF AbcDef AbcDeF AbcDEf AbcDEF AbCdef AbCdeF AbCdEf AbCdEF AbCDef AbCDeF AbCDEf AbCDEF ABcdef ABcdeF ABcdEf ABcdEF ABcDef ABcDeF ABcDEf ABcDEF ABCDef ABcDeF ABcDEf ABcDEF ABCDEF ABCDef ABCDeF ABCDEf ABcDEF ABD * ABD * Plef 10 * Plef ABEF ABD * ABD * Plef 10 * Plef?

Ответы [ 5 ]

1 голос
/ 02 августа 2020

Я бы не стал использовать рекурсию как таковую, а вместо этого использовал бы while l oop:

text=['a','b','c','d','e','f']
remaining_text = text[:]  #copy the array
options = ['']  # we start with an empty string so we can easily append to it
while remaining_text:
    # get the first letter and removes it from the list in one go
    next_letter = remaining_text.pop(0)
    
    # and add one option with lowercase and one with uppercase
    # for every existing option
    options = (
        [option + next_letter.lower() for option in options]
        + [option + next_letter.upper() for option in options]
    )

print(options)
0 голосов
/ 02 августа 2020

При разработке рекурсивных функций для структур данных вы в основном изобретаете принцип индукции. Итак, вам нужны два ингредиента:

  1. Каков базовый вариант? Это результат, когда вы больше не можете разбить свой ввод.
  2. Что такое индуктивный случай? Это то, что вы делаете со сложным вводом, при условии, что его части уже обработаны .

Имея некоторый опыт, вы обычно сразу узнаете, каковы случаи, структурно. Для списков это почти всегда (пустой список) и (работа с первым элементом, учитывая рекурсивный результат (ы) для остальных элементов).

Чтобы перевести это на конкретную задачу:

  1. Мы знаем, что результатом для пустой строки является пустая строка.
  2. Если у нас есть непустая строка, мы берем все возможные комбинации для первой буквы (прописные и строчные). Затем мы предполагаем, что уже знаем все результаты для остальной части строки, и просто формируем продукт с результатами, начинающимися с первых букв.

В коде:

def upper_lower(chars): 
    if len(chars) > 0: 
        first, *rest = chars 
        for combo in upper_lower(rest): 
            yield first.lower() + combo 
            yield first.upper() + combo 
    else: 
        yield ''  

Элегантный Было бы неплохо работать с общими итеративными входами и без промежуточного распределения, но я не нашел короткого, удобочитаемого.

0 голосов
/ 02 августа 2020

Поскольку вы специально просили о рекурсии, это один из способов сделать это:

def alloptions(textlist):
    if len(textlist) == 0:
        return ['']
    return [y + x for y in [textlist[0].lower(), textlist[0].upper()] for x in alloptions(textlist[1:])]

text=['a','b','c','d','e','f']
print(alloptions(text))
0 голосов
/ 02 августа 2020

Вы также можете сделать это, используя itertools.product .

Один из способов сделать это - сгенерировать все возможные продукты True и False, повторяющиеся для количества символов в text, и используйте это, чтобы поместить каждый отдельный символ в нижний или верхний регистр.

from itertools import product

text = 'abcdef'

out = []
for capitalized in product([False, True], repeat=len(text)):
    out.append(''.join([char.upper() if upper else char for char, upper in zip(text, capitalized)]))

print(out)

Вывод:

['abcdef', 'abcdeF', 'abcdEf', 'abcdEF', 'abcDef', 'abcDeF', 'abcDEf', 'abcDEF', 'abCdef', 'abCdeF', 'abCdEf', 'abCdEF', 'abCDef', 'abCDeF', 'abCDEf', 'abCDEF', 'aBcdef', 'aBcdeF', 'aBcdEf', 'aBcdEF', 'aBcDef', 'aBcDeF', 'aBcDEf', 'aBcDEF', 'aBCdef', 'aBCdeF', 'aBCdEf', 'aBCdEF', 'aBCDef', 'aBCDeF', 'aBCDEf', 'aBCDEF', 'Abcdef', 'AbcdeF', 'AbcdEf', 'AbcdEF', 'AbcDef', 'AbcDeF', 'AbcDEf', 'AbcDEF', 'AbCdef', 'AbCdeF', 'AbCdEf', 'AbCdEF', 'AbCDef', 'AbCDeF', 'AbCDEf', 'AbCDEF', 'ABcdef', 'ABcdeF', 'ABcdEf', 'ABcdEF', 'ABcDef', 'ABcDeF', 'ABcDEf', 'ABcDEF', 'ABCdef', 'ABCdeF', 'ABCdEf', 'ABCdEF', 'ABCDef', 'ABCDeF', 'ABCDEf', 'ABCDEF']

Или создав произведение кортежей (char, char.upper()):

from itertools import product

text = 'abcdef'

out = []
for chars in product(*((c, c.upper()) for c in text)):
    out.append(''.join(chars))
    
print(out)
0 голосов
/ 02 августа 2020

Для этого можно использовать рекурсию, см. Ниже. Основное преимущество использования рекурсивного генератора таким образом заключается в том, что вы не накапливаете промежуточные результаты в памяти и не вычисляете значения, которые в конечном итоге не используете. Если вам нужно рассчитать много перестановок, это, вероятно, хорошая идея.

def caps_permutations(sequence):
    if len(sequence) == 0:
        raise ValueError()
    elif len(sequence) == 1:
        element = sequence[0]
        yield [element.lower()]
        yield [element.upper()]
    else:
        # Copy to avoid mutating input sequence
        inner_sequence = copy.copy(sequence)
        element = inner_sequence.pop(0)
        for inner_permutation in caps_permutations(inner_sequence):
            yield [element.lower()] + inner_permutation
            yield [element.upper()] + inner_permutation

text=['a','b','c','d','e','f']

for permutation in caps_permutations(text):
    print(permutation)

Ожидаемый результат:

['a', 'b', 'c', 'd', 'e', 'f']
['A', 'b', 'c', 'd', 'e', 'f']
['a', 'B', 'c', 'd', 'e', 'f']
['A', 'B', 'c', 'd', 'e', 'f']
['a', 'b', 'C', 'd', 'e', 'f']
['A', 'b', 'C', 'd', 'e', 'f']
...
['A', 'B', 'C', 'D', 'E', 'F']

...