Only add to a dict if a condition is met

后端 未结 11 2049
鱼传尺愫
鱼传尺愫 2020-12-05 03:57

I am using urllib.urlencode to build web POST parameters, however there are a few values I only want to be added if a value other than None exists

相关标签:
11条回答
  • 2020-12-05 04:08

    You can clear None after the assignment:

    apple = 'green'
    orange = None
    dictparams = {
        'apple': apple,
        'orange': orange
    }
    for k in dictparams.keys():
        if not dictparams[k]:
            del dictparams[k]
    params = urllib.urlencode(dictparams)
    
    0 讨论(0)
  • 2020-12-05 04:08

    I really like the neat trick in the answer here: https://stackoverflow.com/a/50311983/3124256

    But, it has some pitfalls:

    1. Duplicate if tests (repeated for key and value)
    2. Pesky None: None entry in the resulting dict

    To avoid this, you can do the following:

    apple = 23
    orange = None
    banana = None
    a = {
        'apple' if apple else None: apple,
        'orange' if orange else None : orange,
        'banana' if banana else None: banana,
        None: None,
    }
    del a[None]
    

    Expected Output : {'apple': 23}

    Note: the None: None entry ensures two things:

    1. The None key will always be present (del won't throw an error)
    2. The contents of 'None values' will never exist in the dict (in case you forget to del afterwards)

    If you aren't worried about these things, you can leave it out and wrap the del in a try...except (or check if the None key is present before deling). To address number 2 alternatively, you could also put the conditional check on the value (in addition to the key).

    0 讨论(0)
  • 2020-12-05 04:14
    params = urllib.urlencode({
        'apple': apple,
        **({'orange': orange} if orange else {}),
    })
    
    0 讨论(0)
  • 2020-12-05 04:14

    Another valid answer is that you can create you own dict-like container that doesn't store None values.

    class MyDict:
        def __init__(self):
            self.container = {}
        def __getitem__(self, key):
            return self.container[key]
        def __setitem__(self, key, value):
            if value != None:
                self.container[key] = value
        def __repr__(self):
            return self.container.__repr__()
    
    a = MyDict()
    a['orange'] = 'orange';
    a['lemon'] = None
    
    print a
    

    yields:

    {'orange': 'orange'}
    
    0 讨论(0)
  • 2020-12-05 04:19

    I did this. Hope this help.

    apple = 23
    orange = 10
    a = {
        'apple' : apple,
        'orange' if orange else None : orange
    }
    

    Expected output : {'orange': 10, 'apple': 23}

    Although, if orange = None , then there will be a single entry for None:None. For example consider this :

    apple = 23
    orange = None
    a = {
        'apple' : apple,
        'orange' if orange else None : orange
    }
    

    Expected Output : {None: None, 'apple': 23}

    0 讨论(0)
  • 2020-12-05 04:20

    Pretty old question but here is an alternative using the fact that updating a dict with an empty dict does nothing.

    def urlencode_func(apple, orange=None):
        kwargs = locals().items()
        params = dict()
        for key, value in kwargs:
            params.update({} if value is None else {key: value})
        return urllib.urlencode(params)
    
    0 讨论(0)
提交回复
热议问题