Нечувствительный к регистру 'in' – Python

Мне нравится использовать выражение

if 'MICHAEL89' in USERNAMES: ... 

где USERNAMES – это список


Есть ли способ сопоставить элементы с нечувствительностью к регистру или мне нужно использовать собственный метод? Просто интересно, нужно ли писать дополнительный код для этого.

Спасибо всем!

     if 'MICHAEL89' in (name.upper() for name in USERNAMES): ... 

    В качестве альтернативы:

     if 'MICHAEL89' in map(str.upper, USERNAMES): ... 

    Или, да, вы можете создать собственный метод.

    Я бы сделал обертку, чтобы вы не были инвазивны. Минимально, например …:

     class CaseInsensitively(object): def __init__(self, s): self.__s = s.lower() def __hash__(self): return hash(self.__s) def __eq__(self, other): # ensure proper comparison between instances of this class try: other = other.__s except (TypeError, AttributeError): try: other = other.lower() except: pass return self.__s == other 

    Теперь, if CaseInsensitively('MICHAEL89') in whatever: должен вести себя по мере необходимости (есть ли правая часть – список, dict или set). (Может потребоваться больше усилий для достижения аналогичных результатов для включения строк, во избежание предупреждений в некоторых случаях, связанных с unicode и т. Д.).

    Обычно (по крайней мере, по крайней мере) вы формируете свой объект, чтобы вести себя так, как хотите. name in USERNAMES не зависит от регистра, поэтому USERNAMES необходимо изменить:

     class NameList(object): def __init__(self, names): self.names = names def __contains__(self, name): # implements `in` return name.lower() in (n.lower() for n in self.names) def add(self, name): self.names.append(name) # now this works usernames = NameList(USERNAMES) print someone in usernames 

    Самое замечательное в этом заключается в том, что он открывает путь для многих улучшений без необходимости изменять какой-либо код вне класса. Например, вы можете изменить self.names на набор для более быстрого поиска или вычислить (n.lower() for n in self.names) только один раз и сохранить его в классе и так далее …

    Я думаю, вам нужно написать дополнительный код. Например:

     if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES): ... 

    В этом случае мы формируем новый список со всеми записями в USERNAMES преобразованными в верхний регистр, а затем сравниваем их с этим новым списком.

    Обновить

    Как говорит @viraptor , даже лучше использовать генератор вместо map . См. Ответ @Nathon .

    Вот один из способов:

     if string1.lower() in string2.lower(): ... 

    Вы могли бы сделать

     matcher = re.compile('MICHAEL89', re.IGNORECASE) filter(matcher.match, USERNAMES) 

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

     matcher = re.compile('MICHAEL89', re.IGNORECASE) if any( ifilter( matcher.match, USERNAMES ) ): #your code here 

    Функция ifilter – это itertools, один из моих любимых модулей в Python. Это быстрее, чем генератор, но создает только следующий элемент списка при вызове.