Compare python 'E' letter

Asked

Viewed 168 times

1

I have this code that basically goes through the list new_users and check if there are already some users within current_users.

When mine if converts the names of new_users for uppercase, lowercase, etc., it fails on a possibility, which is when the name 'ze' is like this: 'Ze'. Or any other end name 'E' in the list current_users.

I put other names in the current_users list with the letter 'E' at the end and my code fails to check. What can I do to convert the two lists into lower() and check if there are any repeat users?

current_users = ['ze', 'carmo', 'sofia', 'jeff', 'isa']
new_users = ['ze', 'didao', 'edi', 'taria', 'sofia']


for new_user in new_users:

    if new_user.lower() not in current_users \
            and new_user.upper() not in current_users\
            and new_user.title() not in current_users\
            and new_user.lower() not in current_users:
        print('O nome "' + new_user.title() + '" está disponível.')
    else:
       print('Forneça outro nome.')

3 answers

4


The problem is not only the letter "E", but the fact that the code fails when the list current_users has names that mix uppercase and lowercase letters. After all, only in the new_user that you turn everything into uppercase or lowercase (in your case, you’re comparing ze, Ze and ZE with zE, and then it won’t even work).

If you want to make comparisons case insensitive, can use the method casefold(). This method is similar to lower(), but according to the documentation, he is more "aggressive" and treats special cases, as for example the character ß, which, when converted to capital, becomes "SS" (then 'ß'.upper().lower() returns "ss"):

print('ß'.lower() == 'SS'.lower()) # False
print('ß'.casefold() == 'SS'.casefold()) # True

Of course for letters of a to z not accentuated, will not make so much difference use lower() or casefold(), but finally.

So just apply casefold() in the list of current users, and also in each user you are checking:

current_users = ['ZE', 'carmo', 'SofiA', 'jeff', 'isa']
new_users = ['ze', 'didao', 'edi', 'taria', 'sofia']

current_users_fold = list(map(lambda user: user.casefold(), current_users))
for new_user in new_users:
    if new_user.casefold() not in current_users_fold:
        print('O nome "' + new_user.title() + '" está disponível.')
    else:
       print('Forneça outro nome.')

First I use map to create another list containing the version casefolded of current users. Then I apply the casefold() for every new user I’m checking.

The exit is:

Forneça outro nome.
O nome "Didao" está disponível.
O nome "Edi" está disponível.
O nome "Taria" está disponível.
Forneça outro nome.

Another alternative is to use set to find the intersection between the two lists (i.e., existing users), and use this list to check for non-existent ones:

def ajusta(s):
    return s.casefold()

existentes = list( set(map(ajusta, current_users)) & set(map(ajusta, new_users)) )
nao_existentes = [ new_user for new_user in new_users if new_user.casefold() not in existentes]
print(existentes) # ['sofia', 'ze']
print(nao_existentes) # ['didao', 'edi', 'taria']

Once you have both lists (existing and non-existent users), you can use them any way you want.

  • Thanks, I’m learning python every help is welcome. I edited the code based on yours and gave it right :)

2

In your code, what’s happening is that you’re just making transformations on new_user and not in the current_users, a way to solve this would be by normalizing the two lists and then comparing, for example:

current_users = ['zE', 'carmo', 'sofia', 'jeff', 'isa']
new_users = ['ze', 'didao', 'edi', 'taria', 'sofia']

current_users_lower = [current_user.lower() for current_user in current_users]
new_users_lower = [new_user.lower() for new_user in new_users ]

for new_user in new_users_lower:

    if new_user not in current_users_lower:
        print('O nome "' + new_user + '" está disponível.')
    else:
       print('"' + new_user + '" não está disponível, forneça outro nome.')

Another way would be using the set, for example:

current_users = ['zE', 'carmo', 'sofia', 'jeff', 'isa']
new_users = ['ze', 'didao', 'edi', 'taria', 'sofia']

current_users_lower = {current_user.lower() for current_user in current_users}
new_users_lower = {new_user.lower() for new_user in new_users }
duplicated = current_users_lower.intersection(new_users_lower)

print('Nomes já utilizados: {}'.format(', '.join(duplicated)))
print('Nomes disponíveis: {}'.format(', '.join(new_users_lower - duplicated)))
  • 1

    Your version with set is better than mine, I forgot that it can subtract... :-)

1

Well, you basically need to convert all the names on the list current_users for lowercase. See the code below:

current_users = ['zE', 'carmo', 'sofia', 'jeff', 'isa']
new_users = ['ze', 'didao', 'edi', 'taria', 'sofia']

# Converte todos os nomes da lista current_users para minúsculo.
c_users = []
for user in current_users:
    c_users.append(user.lower())
current_users = c_users

for new_user in new_users:

    if new_user.lower() not in current_users:
        print('O nome "' + new_user.title() + '" está disponível.')
    else:
       print('Forneça outro nome.')

Browser other questions tagged

You are not signed in. Login or sign up in order to post.