username = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
...
Alternatively:
if username.upper() in map(str.upper, USERNAMES):
...
Or, yes, you can make a custom method.
Answer from nmichaels on Stack Overflowusername = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
...
Alternatively:
if username.upper() in map(str.upper, USERNAMES):
...
Or, yes, you can make a custom method.
str.casefold is recommended for case-insensitive string matching. @nmichaels's solution can trivially be adapted.
Use either:
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
Or:
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
As per the docs:
Casefolding is similar to lowercasing but more aggressive because it is intended to remove all case distinctions in a string. For example, the German lowercase letter 'ß' is equivalent to "ss". Since it is already lowercase,
lower()would do nothing to 'ß';casefold()converts it to "ss".
Here is the relevant section of code as I originally wrote it:
elif choice == "4":
print('What would you like to find? ')
search_item = input()
if search_item not in thislist:
print ("Not found in this list:")
else:
print ("Found in this list:")
print(', '.join(thislist))...but it turned out that this was case-sensitive to user input, which is not desired, so I tried...
elif choice == "4":
print('What would you like to find? ')
search_item = input()
if (search_item.lower() not in thislist.lower()):
print ("Not found in this list:")
else:
print ("Found in this list:")
print(', '.join(thislist))...as mentioned, for instance here. But it doesn't work, and I get...
Traceback (most recent call last): File "main.py", line 39, in <module> if (search_item.lower() not in thislist.lower()): AttributeError: 'list' object has no attribute 'lower'
I'm guessing that maybe it's because one or both of these isn't a string, but I'm not sure how to fix that if that is really the problem. Any help please? TIA.
BTW, I'm using https://repl.it, as I don't have a Python IDE installed on my home PC.
Hi everyone, I am just starting to learn how to code, running into a problem when I try to compare two lists, my code is below:
current_users = ['May', 'April', 'Wu', 'Su', 'Lulu'] new_users = ['may', 'mike', 'jones', 'chow', 'paul'] for new_user in new_users: if new_user in current_users: print('username '+new_user+' is not available.') else: print('welcome')
when I try to make the current_users list case insensitive for comparing, I used:
current_users.lower() ==['may', 'april', 'wu', 'su', 'lulu']
when I run the code, result in a violation, stated that list can not have contribute .lower().
Is there anyway to make the list case insensitive?
thanks in advance.
Hi all,
I'm learning python and have been trying to figure out how to properly compare lists for case insensitivity. If I have two lists, where the first list contains the current user names and the second list is a list of new usernames, how do I get to make sure that if a new user name John won't conflict with a username in the current users of JoHn or JOHN and vice versa?
I have this so far:
current_users = ['John', 'BiLl', 'simcitizzon', 'mIke', 'cHarlie', 'admin']
new_users = ['john', 'simcitiZzon', 'ralphwiggum', 'cherrymcsperry', 'sweettooth347']
for user in new_users:
if user in current_users:
print("Sorry, " + user + " is taken.")
else:
print(user + ", this username is available")One of the more elegant ways you can do this is to use a generator:
>>> list = ['ADMISSION' ,'Colace','100','mg', 'b.i.d.' , 'insulin','Lente','12']
>>> next(i for i,v in enumerate(list) if v.lower() == 'mg')
3
The above code makes a generator that yields the index of the next case insensitive occurrence of mg in the list, then invokes next() once, to retrieve the first index. If you had several occurrences of mg in the list, calling next() repeatedly would yield them all.
This also has the benefit of being marginally less expensive, since an entire lower cased list need not be created; only as much of the list is processed as needs to be to find the next match.
you can ignore the cases by converting the total list and the item you want to search into lowercase.
>>> to_find = 'MG'
>>> old_list = ['ADMISSION' ,'Colace','100','mg', 'b.i.d.' , 'insulin','Lente','12']
>>> new_list = [item.lower() for item in old_list]
>>> new_list.index(to_find.lower())
3
Assuming ASCII strings:
string1 = 'Hello'
string2 = 'hello'
if string1.lower() == string2.lower():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
As of Python 3.3, casefold() is a better alternative:
string1 = 'Hello'
string2 = 'hello'
if string1.casefold() == string2.casefold():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
If you want a more comprehensive solution that handles more complex unicode comparisons, see other answers.
Comparing strings in a case insensitive way seems trivial, but it's not. I will be using Python 3, since Python 2 is underdeveloped here.
The first thing to note is that case-removing conversions in Unicode aren't trivial. There is text for which text.lower() != text.upper().lower(), such as "ß":
>>> "ß".lower()
'ß'
>>> "ß".upper().lower()
'ss'
But let's say you wanted to caselessly compare "BUSSE" and "Buße". Heck, you probably also want to compare "BUSSE" and "BUẞE" equal - that's the newer capital form. The recommended way is to use casefold:
str.casefold()
Return a casefolded copy of the string. Casefolded strings may be used for caseless matching.
Casefolding is similar to lowercasing but more aggressive because it is intended to remove all case distinctions in a string. [...]
Do not just use lower. If casefold is not available, doing .upper().lower() helps (but only somewhat).
Then you should consider accents. If your font renderer is good, you probably think "ê" == "ê" - but it doesn't:
>>> "ê" == "ê"
False
This is because the accent on the latter is a combining character.
>>> import unicodedata
>>> [unicodedata.name(char) for char in "ê"]
['LATIN SMALL LETTER E WITH CIRCUMFLEX']
>>> [unicodedata.name(char) for char in "ê"]
['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']
The simplest way to deal with this is unicodedata.normalize. You probably want to use NFKD normalization, but feel free to check the documentation. Then one does
>>> unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
True
To finish up, here this is expressed in functions:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
fruit.lower() in the for loop won't work as the error message implies, you can't assign to a function call..
What you could do is create an auxiliary structure (set here) that holds the lowercase items of the existing fruits in fruits, and, append to fruits if a fruit.lower() in fruit_add isn't in the t set (containing the lowercase fruits from fruits):
t = {i.lower() for i in fruits}
for fruit in fruits_add:
if fruit.lower() not in t:
fruits.append(fruit)
With fruits now being:
print(fruits)
['Apple', 'banana', 'Kiwi', 'melon', 'strawberry']
I wouldn't use the lower() function there. Use lower like this:
for fruit in fruits_add:
if fruit.lower() in fruits:
print("already in list")