How to check if a List Argument is None

百般思念 提交于 2021-01-29 09:11:56

问题


I am doing this problem set, and I cannot get passed the Test Case for when the List is None.

I have tested for almost all the cases, and I have noticed that other users got it right with a code that is very similar to mine, I need help debugging and checking if I am missing a test case in my Conditionals.

The test cases that come back negative are testing to see if the List is None, which I found out by testing in the Python interpreter that it does not necessarily imply empty.

Here is the Code:

def likes(names):

    for i in names:

        if not names:
            return "no one likes this"
        elif len(names) <= 0:
            return "no one likes this"
        elif len(names) == 1:
            text = "{} likes this"
            return text.format(names[0])
        elif names == None:
            return "no one likes this"
        elif len(names) > 2 and len(names) <= 4 and len(names) != 3:
            additional = len(names) - 2
            text = "{}, {} and {} others like this"
            return text.format(names[0], names[1], additional)
        elif len(names) > 2 and len(names) > 4 and len(names) != 3:
            additional = len(names) - 2
            text = "{}, {} and {} others like this"
            return text.format(names[0], names[1], additional)
        elif len(names) == 2:
            text = "{} and {} like this"
            return text.format(names[0], names[1])
        elif len(names) == 3:
            text = "{}, {} and {} like this"
            return text.format(names[0], names[1], names[2])
        else:
            text = "{} likes this"
            return text.format(names[0])

回答1:


I am not sure what you are trying to do with the for i in names: line in your code. I assume you are trying to iterate through the list of names. If this is the case, I would change the line to for name in names:.

Keep in mind that list = None is different from list = []. When list = None, list is undefined. On the other hand, list = [] signifies an empty list.

Here is an example that may be helpful.

def checkListVal(valList):
# Checks to see if valList stores some data
if valList == None:
    print("valList is undefined")
    # Returns out of this function
    return

# Checks to see if the list is empty
if len(valList) == 0:
    print("valList is empty")
    return

for val in valList:
    if val == "val1":
        print("val1 in valList")
    elif val == "val2":
        print("val2 in valList")
    else:
        print("val equals " + val)

valList1 = ["val1", "val2", "val3"]
valList2 = []
valList3 = None

checkListVal(valList1)
print()

checkListVal(valList2)
print()

checkListVal(valList3)

The output is as follows:

val1 in valList
val2 in valList
val equals val3

valList is empty

valList is undefined



回答2:


Thanks to @JohnGordon, I only needed to remove the for loop around the conditionals, it works just fine

def likes(names):
    if not names:
        return "no one likes this"
    elif len(names) <= 0:
        return "no one likes this"
    elif len(names) == 1:
        text = "{} likes this"
        return text.format(names[0])
    elif names == None:
        return "no one likes this"
    elif len(names) > 2 and len(names) <= 4 and len(names) != 3:
        additional = len(names) - 2
        text = "{}, {} and {} others like this"
        return text.format(names[0], names[1], additional)
    elif len(names) > 2 and len(names) > 4 and len(names) != 3:
        additional = len(names) - 2
        text = "{}, {} and {} others like this"
        return text.format(names[0], names[1], additional)
    elif len(names) == 2:
        text = "{} and {} like this"
        return text.format(names[0], names[1])
    elif len(names) == 3:
        text = "{}, {} and {} like this"
        return text.format(names[0], names[1], names[2])
    else:
        text = "{} likes this"
        return text.format(names[0])



回答3:


The main issue is that if None is a possible argument, the for loop will crash. As mentioned in the comments, this loop isn't relevant to the logic anyway because it simply returns on the first iteration. We're only interested in properties about the length of the list (if it exists), not its elements, so remove the loop.

Having said that, the logic here is extremely confusing and there are many redundant branches. Conditionals that have more than 3 or 4 branches or nesting greater than a couple levels are difficult to reason about and should be eliminated.

  • The branch

    elif len(names) > 2 and len(names) > 4 and len(names) != 3:
    

    can be simplified to elif len(names) > 4 because if len(names) is greater than 4, we know for sure it's definitely != 3 and > 2.

  • The branch if not names: covers cases names is None as well as len(names) <= 0 (the < is unnecessary here), so we can toss out two more branches.

  • The branch

    elif len(names) > 2 and len(names) <= 4 and len(names) != 3:
    

    is the same as elif len(names) == 4.

Taking a step back, there are only 5 cases:

  1. we have no names
  2. we have 1 name
  3. we have 2 names
  4. we have 3 names
  5. we have 4 or more names

Here's a re-write to express this clearly:

def likes(names):
    if not names:
        return "no one likes this"
    elif len(names) == 1:
        return f"{names[0]} likes this"
    elif len(names) == 2:
        return f"{names[0]} and {names[1]} like this"
    elif len(names) == 3:
        return f"{names[0]}, {names[1]} and {names[2]} like this"

    return f"{names[0]}, {names[1]} and {len(names) - 2} others like this"

if __name__ == "__main__":
    names = ["alice", "bob", "carol", "doug", "eric", "fred"]
    print("None =>", likes(None))

    for i in range(len(names)):
        print(names[:i], "=>", likes(names[:i]))

Output:

None => no one likes this
[] => no one likes this
['alice'] => alice likes this
['alice', 'bob'] => alice and bob like this
['alice', 'bob', 'carol'] => alice, bob and carol like this
['alice', 'bob', 'carol', 'doug'] => alice, bob and 2 others like this
['alice', 'bob', 'carol', 'doug', 'eric'] => alice, bob and 3 others like this


来源:https://stackoverflow.com/questions/59201962/how-to-check-if-a-list-argument-is-none

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!