wake-up-neo.com

Groß- und Kleinschreibung wird nicht berücksichtigt. - Python

Ich liebe es, den Ausdruck zu benutzen

if 'MICHAEL89' in USERNAMES:
    ...

dabei ist USERNAMES eine Liste


Gibt es eine Möglichkeit, Elemente mit Groß-/Kleinschreibung zuzuordnen, oder muss ich eine benutzerdefinierte Methode verwenden? Ich frage mich nur, ob es notwendig ist, zusätzlichen Code dafür zu schreiben.

Danke an alle!

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

Alternative:

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

Oder ja, Sie können eine benutzerdefinierte Methode erstellen.

159
nmichaels

Ich würde ein Wrapper machen, damit Sie nicht invasiv sein können. Zum Beispiel:

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

Nun sollte sich if CaseInsensitively('MICHAEL89') in whatever: wie gewünscht verhalten (ob die rechte Seite eine Liste, ein Diktat oder eine Menge ist). (Möglicherweise ist mehr Aufwand erforderlich, um ähnliche Ergebnisse für das Einschließen von Zeichenfolgen zu erzielen. Vermeiden Sie in einigen Fällen Warnungen, die unicode usw. betreffen.).

19
Alex Martelli

Normalerweise (zumindest in oop) gestalten Sie Ihr Objekt so, dass es sich so verhält, wie Sie es möchten. name in USERNAMES unterscheidet nicht zwischen Groß- und Kleinschreibung, daher muss USERNAMES geändert werden:

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

Das Tolle daran ist, dass es den Weg für viele Verbesserungen ebnet, ohne dass Code außerhalb der Klasse geändert werden muss. Zum Beispiel könnten Sie das self.names zu einem Satz für schnellere Suchvorgänge oder zum Berechnen des (n.lower() for n in self.names) nur einmal und in der Klasse speichern und so weiter ...

10
Jochen Ritzel

Ich denke, Sie müssen etwas zusätzlichen Code schreiben. Beispielsweise:

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

In diesem Fall erstellen wir eine neue Liste mit allen Einträgen in USERNAMES, die in Großbuchstaben umgewandelt wurden, und vergleichen sie dann mit dieser neuen Liste.

Update

Wie @ viraptor sagt, ist es sogar besser, einen Generator anstelle von map zu verwenden. Siehe @ Nathon 's Antwort .

6
Manoj Govindan

Hier ist eine Möglichkeit:

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

Damit dies funktioniert, müssen sowohl string1 und string2 Objekte müssen vom Typ string sein.

6
User

str.casefold Wird für einen String-Abgleich empfohlen, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird. @ nmichaels's Lösung kann trivial angepasst werden.

Benutze das eine oder das andere:

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

Oder:

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

Gemäß docs :

Casefolding ähnelt Lowercasing, ist jedoch aggressiver, da alle Fallunterscheidungen in einer Zeichenfolge entfernt werden sollen. Zum Beispiel ist der deutsche Kleinbuchstabe "ß" gleichbedeutend mit "ss". Da es sich bereits um Kleinbuchstaben handelt, würde lower() nichts gegen 'ß' unternehmen. casefold() konvertiert es in "ss".

5
jpp

Du könntest es tun

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

Update: ein bisschen rumgespielt und ich denke man könnte einen besseren Kurzschlussansatz mit bekommen

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

Die Funktion ifilter stammt aus itertools, einem meiner Lieblingsmodule in Python. Es ist schneller als ein Generator, erstellt jedoch nur dann das nächste Element der Liste, wenn es aufgerufen wird.

4
wheaties

Meine 5 (falschen) Cent

'a' in "" .join (['A']). lower ()

AKTUALISIEREN

Autsch, stimme voll und ganz @jpp zu, ich behalte als Beispiel für schlechte Praxis :(

0
GBrian