Home > Software engineering >  How can I make my output exclude an element if it equals to zero?
How can I make my output exclude an element if it equals to zero?

Time:11-23

So I created this code with the help of Stack Overflow users.

def get_name(string):
    return string.replace(" ", "").replace("-", "")

def gnames(input_list: list):
    output = {}
    for entry in input_list:
        if '->' in entry:
            names = entry.split('->')
            output[names[1]] = output[names[0]]
            output[names[0]] = 0
        else:
            name = get_name(entry)
            if name not in output:
                output[name] = 0
            if "  " in entry:
                output[name]  = 1
            if "--" in entry:
                output[name] -= 1
    return output
print(gnames(["Jim--", "John--", "Jordan--", "Jim  ", "John--", "Jeff--", "June  ", "June->Jim"]))

and this returns

{'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1, 'June': 0}

Now this is right, but I want gnames() to return only the non zero values negative numbers or positive numbers are fine

so in my example, there's 'June' = 0

and I want the output of gnames() to exclude 'June' = 0 or if any other person has a 0... I want gnames() to exclude it...

so my output in thiscase, should return

{'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1}

How can I do that??

CodePudding user response:

A dictionary comprehension makes this pretty simple. If we start out with gnames being {'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1, 'June': 0} we can write a dictionary comprehension that will filter out the zero value.

>>> gnames = {'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1, 'June': 0}
>>> {k: v for k, v in gnames.items() if v != 0}
{'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1}
>>>

CodePudding user response:

Also using dictionary comprehension, you can alter your return like so:

return {x:output[x] for x in output if output[x] != 0}

Description of what this does:

# for each element in output
#    if element['name'] != 0 then keep it

Full code:

def get_name(string):
    return string.replace(" ", "").replace("-", "")

def gnames(input_list: list):
    output = {}
    for entry in input_list:
        if '->' in entry:
            names = entry.split('->')
            output[names[1]] = output[names[0]]
            output[names[0]] = 0
        else:
            name = get_name(entry)
            if name not in output:
                output[name] = 0
            if "  " in entry:
                output[name]  = 1
            if "--" in entry:
                output[name] -= 1
    return {x:output[x] for x in output if output[x] != 0}


print(gnames(["Jim--", "John--", "Jordan--", "Jim  ", "John--", "Jeff--", "June  ", "June->Jim"]))

# Sample output
# {'Jim': 1, 'John': -2, 'Jordan': -1, 'Jeff': -1}

CodePudding user response:

If you want to avoid an explicit in check to see if the key exists in the dictionary first else set a default value of 0, you can use a collections.defaultdict which is a dict sub-type which automatically sets a default value if the key is not in dict.

So your code could be simplified with defaultdict(int), then with a sign to delta (change) mapping for a slight improvement, then finally you can opt to delete key from the dict if the result of addition is a 0 value; this can be used to avoid the need of a dict comprehension in the return statement altogether.

So now with all the changes added, the end-to-end code looks like below:

from collections import defaultdict


def get_name(string):
    return string.replace(" ", "").replace("-", "")


def gnames(input_list: list):
    output = defaultdict(int)
    sign_to_delta = {'  ': 1,
                     '--': -1}

    for entry in input_list:
        if '->' in entry:
            from_, to = entry.split('->')
            # Use `pop` to retrieve and also delete the key from dict
            # instead of assigning the value as 0, which is already the
            # default behavior if the key is not present.
            output[to] = output.pop(from_)
        else:
            name = get_name(entry)
            for sign in sign_to_delta:
                if sign in entry:
                    result = output[name]   sign_to_delta[sign]
                    if result:
                        output[name] = result
                    else:
                        del output[name]

    return output


print(gnames(["Jim--", "John--", "Jordan--", "Jim  ", "John--", "Jeff--", "June  ", "June->Jim"]))
print(gnames(["Jean  ", "Jean--", "Jean--", "Jean  "]))

Out:

defaultdict(<class 'int'>, {'John': -2, 'Jordan': -1, 'Jeff': -1, 'Jim': 1})
defaultdict(<class 'int'>, {})
  • Related