Поиск всех возможных перестановок регистра в Python

Мне нужно вернуть список всех возможных перестановок case строки в python.

Например, ввод "ar" должен возвращать:

[ 'ar','Ar','aR','AR']  

or "arc":

[ 'arc','Arc','ARc','aRc','aRC','ARC']

person nekosune    schedule 22.07.2011    source источник
comment
То, о чем вы просите, - это в основном алгоритм, если вы знаете алгоритм, вы можете реализовать его на любом языке, который вы хотите (Python). Все, что я могу вам в этом помочь, это: рекурсия. (попробовать что-то на бумаге может помочь)   -  person Aerus    schedule 22.07.2011
comment
@nekosune: Из любопытства, для чего вы используете эту функцию? Я обеспокоен тем, что, возможно, вы используете это, чтобы сравнить строку неизвестного регистра, чтобы увидеть, соответствует ли она слову. Если это так, есть лучшие способы сделать это.   -  person Bryan Oakley    schedule 22.07.2011
comment
@Bryan Нет, если бы я делал это, использовал бы tolower, я использую движок приложения и хочу вернуть запрос, который нечувствителен к регистру, используя для этого часть GQL in, поскольку это гарантировано быть короткими словами.   -  person nekosune    schedule 22.07.2011
comment
Самый простой способ - itertools.product(*zip(string.lower(), string.upper())).   -  person agf    schedule 11.04.2012


Ответы (2)


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

import itertools

chars = "abc"
results = list(map(''.join, itertools.product(*zip(chars.upper(), chars.lower()))))

print(results)
>>>['ABC', 'ABc', 'AbC', 'Abc', 'aBC', 'aBc', 'abC', 'abc']

Чтобы представить, как это работает:

  1. zip создает для нас 3 "оси", каждая с 2 точками (верхний/нижний регистр):
    [('A', 'a'), 
     ('B', 'b'), 
     ('C', 'c')]
    
  2. product берет декартово произведение этих осей, то есть 8 возможных координат, соответствующих углам единичного куба, который он создает:
enter image description here enter image description here
1. Create axes 2. Take Cartesian product
  1. ''.join объединяет кортежи для вывода строки: ('A','B','C') -> 'ABC'
person iacob    schedule 27.03.2021

person    schedule
comment
Большое спасибо, это было идеально. Алгоритмы, особенно рекурсивные, всегда были моим слабым местом. - person nekosune; 22.07.2011
comment
Я немного запутался. Какой смысл сравнивать прописные и строчные буквы (поскольку 'a' никогда не должно равняться 'A') и нарезать первый символ (по сравнению с input_string[0])? - person Maximilian Burszley; 02.09.2018
comment
Чтобы избежать возврата двух результатов, когда есть символ без различия между старшими и низшими, например, '.'.upper() == '.'.lower() - person Paul McMillan; 02.07.2019