I'm working on a project where I have a list of items where some are capitalized (list is currently incomplete because debugging). I need to check if the user's input is in the list, and I'd rather it not be case sensitive. I tried using the lower() method, but it doesn't work for lists. Is there a way to get the same effect as that in the context of this code?
itemList = ['Dirt', 'Oak Log']
def takeName():
itemName = ''
while itemName == '':
itemName = input('What Minecraft item would you like the crafting recipe for?\n')
try:
itemName = int(itemName)
except ValueError:
if itemName.lower() not in itemList.lower():
print('Not a valid Minecraft item name or ID!\n')
itemName = ''
elif itemName.lower() in itemList.lower():
itemName = itemList.lower().index(itemName)
return itemName
CodePudding user response:
You can use list comprehension to convert the list items to lowercase. For example:
itemList_lower = [x.lower() for x in itemList]
Then use itemList_lower
in the places in your code where you tried using itemList.lower()
.
CodePudding user response:
Unfortunately, there is no built-in method that set all the strings of a list to lower case.
If you think about it, it would be inconsistent to develop, because in Python a list can store object of different type, it would be incoherent about the purpose of the data structure itself.
So, you should design and develop an algorithm to do that.
Do not worry though, with "list comprehension" it's quick, simple and elegant, in fact:
lowered_list = [item.lower() for item in itemList]
so now, you have a new list named "lowered_list" that contains all the strings you have stored in the other list, but in lower case.
Cool, isn't it?
CodePudding user response:
You can't use a string function on a list in order to apply this function to all list items. You'll have to apply the function using a list comprehension or using the map function.
Using a list comprehension:
lowerItemList = [item.lower() for item in itemList]
A list comprehension is basiccally a more efficient way and shorter to write short for loops. The above code would be the same as this:
lowerItemList = []
for item in itemList:
itemLower = item.lower()
loserItemList.append(itemLower)
Another way to do this is using the map function. This function applies a function to all items of an iterable.
lowerItemList = list(map(str.lower, itemList))
As this is an a bit more complicated example, here's how it works:
We are using the map function to apply the str.lower
function on our item list. Calling str.lower(string)
is actually the same as calling string.lower()
. Python does this already for you.
So, our result will contain a map object containing all the strings in their lowered form. We need to convert this map object into a list object, as a map object is an iterator and this does not support indexing and many of the list class' methods.
CodePudding user response:
You want a case-insensitive lookup but you want to return a value as it's defined in itemList. Therefore:
itemList = ['Dirt', 'Oak Log']
itemListLower = [e.lower() for e in itemList] # normal form
def takeName():
while True:
itemName = input('What Minecraft item would you like the crafting recipe for? ')
try:
idx = itemListLower.index(itemName.lower()) # do lookup in the normal form
# as the two lists are aligned you can then return the value from the original list using the same index
return itemList[idx]
except ValueError:
print(f'{itemName} is not a valid selection') # user will be promted to re-enter
print(takeName())
Output:
What Minecraft item would you like the crafting recipe for? banana
banana is not a valid selection
What Minecraft item would you like the crafting recipe for? oak log
Oak Log