Нужно понять, почему моя функция Python не выполняет надлежащее сравнение строк - PullRequest
1 голос
/ 25 марта 2019

Я заканчиваю онлайн-курс, в котором используется Python 3, и ниже - приглашение, которое я получил:

Напишите функцию с именем is_valid. is_valid должен занять два параметры: строка для проверки и строка всех допустимых символы.

is_valid должен возвращать логическое значение True, если все символы в строке для проверки присутствуют в строке действительных символов. Должен возвращать False, если любой символ в проверенной строке не появляется.

Я определил функцию, которая принимает два параметра, упомянутых в задаче: строку (которую в моем коде я называю строкой) и строку допустимых символов (которую я назвал validcharacters).

Я не должен использовать какие-либо из встроенных строковых функций Python, поэтому я решил написать цикл for с моей индексной переменной, называемой символом, который индексирует через строку. После того, как написан цикл for, я написал оператор if, в котором проверяется, есть ли символ (переменная индекса) в допустимых символах. Если это так, он возвращает True. В противном случае я написал инструкцию else, которая возвращает False.

def is_valid(string, validcharacters):
    for character in string:
        if character in validcharacters:
            return True
        else:
            return False

Ниже приведены несколько тестовых примеров для работы:

sample_valid_string = "1234-5678-9011-1111"
sample_invalid_string = "1234!5678.9011?1111"
valid_characters = "0123456789-"

print(is_valid(sample_valid_string, valid_characters))
print(is_valid(sample_invalid_string, valid_characters))

Я ожидаю, что выходные данные (для тестовых случаев, которые я перечислил выше) будут True и False соответственно. Однако, как написан мой код, он возвращает True и True. Я обнаружил, что при отладке он проходит только по первому символу моего кода и не может повторять другие символы. Я не уверен, как мне нужно переписать свой код, чтобы он проходил через другие символы перед возвратом True или False. Нужно ли мне переставлять свои декларации? Они заставляют функцию заканчиваться слишком рано?

Ответы [ 5 ]

1 голос
/ 25 марта 2019

Учитывая то, как вы определили is_valid, вы напрямую возвращаете True, если первый символ в string находится в valid_characters.Вы должны возвращать True только после того, как проверили, что все символы действительны.Вместо этого вы должны сделать что-то вроде:

def is_valid(string, validcharacters):
    for character in string:
        if character not in validcharacters:
            return False
    return True

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

def is_valid(string, validcharacters):
    return all(i in valid_characters for i in string)

Где all вернет True, когда все элементы в выражении генератора также True.


Возвращение в этом случае:

print(is_valid(sample_valid_string, valid_characters))
print(is_valid(sample_invalid_string, valid_characters))

True
False
0 голосов
/ 25 марта 2019

Помимо других ответов, вы можете реорганизовать эту функцию, используя all().Эта функция возвращает истину, если каждое проверенное условие истинно, в противном случае она вернет ложь.

def is_valid(string, validcharacters):
    # every character has to be in valid_characters for this to return 'True', 
    # otherwise it returns 'False'
    return all(character in valid_characters for character in string)
0 голосов
/ 25 марта 2019
def is_valid(string, validcharacters):
    #Use a variable to track unmatched characters
    flag = True 
    for character in string:
        #If you find a unmatched char, set var to flag to False and break
        if character not in validcharacters: 
            flag = False 
            break
    return flag
0 голосов
/ 25 марта 2019

Ваша функция возвращается слишком рано.

Прямо сейчас он видит, что первый символ, 1, находится в ваших допустимых символах, и возвращает true. Вам нужно убедиться, что вся строка верна. Отложите ваш return True, пока не достигнете конца цикла.

def is_valid(string, validcharacters):
    for character in string:
        if character in validcharacters:
            continue
        else:
            return False
    return True

Примечание: у него довольно большой большой O (https://en.wikipedia.org/wiki/Big_O_notation) из O (N ^ 2), так как он просматривает каждый символ в действительных символах для поиска совпадения. Если вы хотите улучшить его, вы можно было бы рассмотреть приведение списка действительных символов в виде набора (https://docs.python.org/3.7/library/stdtypes.html#set-types-set-frozenset) символов. Поиск совпадения в наборе - это O (1) по сравнению со списком O (n).

0 голосов
/ 25 марта 2019

return немедленно выходит из функции, поэтому, как структурирован ваш цикл, он запускается только один раз.

Реорганизуйте ваш цикл так, чтобы он возвращал False, если обнаружил недопустимый символ, и ждал возврата Trueтолько когда он проходит через строку без поиска недопустимых символов:

def is_valid(string, validcharacters):
    for character in string:
        if character not in validcharacters:
            return False
    return True
...