简体   繁体   English

需要深入了解为什么我的 Python 函数没有对字符串进行正确的比较

[英]Need insight into why my Python function isn't doing a proper comparison of strings

I'm completing an online course that utilizes Python 3 and below is the prompt I received:我正在完成一个使用 Python 3 的在线课程,下面是我收到的提示:

Write a function called is_valid.编写一个名为 is_valid 的函数。 is_valid should take two parameters: a string to check, and a string of all valid characters. is_valid 应该接受两个参数:一个要检查的字符串和一个包含所有有效字符的字符串。

is_valid should return the boolean True if all the characters in the string to check are present in the string of valid characters.如果要检查的字符串中的所有字符都存在于有效字符的字符串中,则 is_valid 应返回布尔值 True。 It should return False if any character in the checked string does not appear.如果检查字符串中的任何字符没有出现,它应该返回 False。

I have defined a function that takes in the two parameters mentioned in the problem, a string (which in my code I call string)), and a string of acceptable characters (which I called validcharacters).我已经定义了一个函数,它接受问题中提到的两个参数,一个字符串(在我的代码中我称之为字符串))和一个可接受字符的字符串(我称之为有效字符)。

I'm not supposed to use any of Python's built-in string functions, so I decided to write a for loop with my index variable being called character that indexes through string.我不应该使用任何 Python 的内置字符串函数,所以我决定编写一个 for 循环,我的索引变量被称为字符,通过字符串索引。 After that for loop is written, I then wrote an if statement that looks to see if character (index variable) is in validcharacters.写完 for 循环之后,我写了一个 if 语句,查看字符(索引变量)是否在 validcharacters 中。 If it is, it returns True.如果是,则返回 True。 Otherwise, I wrote an else statement which returns False.否则,我写了一个返回 False 的 else 语句。

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

Below are some test cases to work with:以下是一些可以使用的测试用例:

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))

I expect the output (for the test cases I listed above) to be True and False respectively.我希望输出(对于我上面列出的测试用例)分别为 True 和 False。 However, the way my code is written, it returns True and True.但是,按照我的代码编写方式,它返回 True 和 True。 I found out through debugging it only iterates through the first character of my code and fails to iterate the other characters.我通过调试发现它只迭代我代码的第一个字符,而无法迭代其他字符。 I'm not sure how I need to re-write my code in order to ensure it goes through other characters before returning True or False.我不确定我需要如何重写我的代码以确保它在返回 True 或 False 之前通过其他字符。 Do I need to re-position my return statements?我需要重新定位我的退货声明吗? Are they causing the function to end too soon?他们是否导致功能过早结束?

Given the way you've defined is_valid , you are directly returning True if the first character in string is in valid_characters .鉴于你定义的方式is_valid ,你是直接返回True ,如果在第一个字符stringvalid_characters You should only be returning True once you've checked all characters are valid.只有在检查所有字符都有效后,才应该返回True You should instead be doing something like:相反,您应该执行以下操作:

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

Note that from the docs, this is the proposed equivalent of all , which could be used to simplify the above to:请注意,从文档中,这是提议的all等价物,可用于将上述内容简化为:

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

Where all will return True when all elements in the generator expression are also True .all将返回True当发电机表达的所有元素也True


Returning in this case:在这种情况下返回:

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

True
False

return exits the function immediately, so the way your loop is structured, it only ever runs once. return立即退出函数,所以你的循环的结构方式,它只运行一次。

Reorganize your loop so it returns False if it finds an invalid character, and waits to return True only when it makes it all the way through the string without finding any invalid characters:重新组织您的循环,以便在找到无效字符时返回 False,并且仅当它一直通过字符串而没有找到任何无效字符时才等待返回 True:

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

Your function is returning too early.您的函数返回得太早。

Right now, it sees that the first character, 1, is in your valid characters, and returns true.现在,它看到第一个字符 1 在您的有效字符中,并返回 true。 What you want is to ensure that the whole string is valid.您想要的是确保整个字符串有效。 Postpone your return True until you've reached the end of your loop.推迟return True直到循环结束。

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

Side note: this has a pretty bad big O ( https://en.wikipedia.org/wiki/Big_O_notation ) of O(N^2), as it iterates through every character in validcharacters to look for a match.旁注:这有一个非常糟糕的 O(N^2) 的大 O( https://en.wikipedia.org/wiki/Big_O_notation ),因为它遍历 validcharacters 中的每个字符以查找匹配项。 If you want to improve it, you could consider casting the validcharacters list as a set ( https://docs.python.org/3.7/library/stdtypes.html#set-types-set-frozenset ) of characters.如果你想改进它,你可以考虑将 validcharacters 列表转换为一组( https://docs.python.org/3.7/library/stdtypes.html#set-types-set-frozenset )字符。 The lookup for a match in a set is O(1) as compared to a list O(n).与列表 O(n) 相比,在集合中查找匹配项是 O(1)。

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

Aside from the other answers, you can refactor this function using all() .除了其他答案之外,您还可以使用all()重构此函数。 This function returns true if every single condition that was checked is true, otherwise it will return false.如果检查的每个条件都为真,则此函数返回真,否则将返回假。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM