Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

257
Views
Generating a dictionary of parameters from keyword arguments

I'm trying to generate a dict containing the names and the value of the non-None parameters current call. This very much feels like something that should be a built-in, but can't find anything that quite does it in the Python documentation.

For example, when

def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):

   # code to generate dict of non-`None` named arguments (see below)

   ...  # other things happen later

is called with the parameters foo(limit=5, lower_bound=100), I need the following dict: {limit=5, lower_bound=100}.

Is there something that conveniently does that for me?


Potential Solutions

So far, I have looked into the following, all of which seem flawed:

  1. Manually making lists (which has a downside of having more places to things to make changes if, for example, an argument has its name changed)
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    keys = ('limit', 'offset', 'lower_bound', 'upper_bound')
    values = (limit, offset, lower_bound, upper_bound)
    magic_dict = {k: v for k, v in zip(keys, values) if v is not None}
  1. locals() — link — which would need everything removed that shouldn't make it into the dictionary (i.e. the keys with the value of None). This also seems potentially error prone if variables definitions get added above the magic dictionary code, which would also need to be removed.
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    magic_dict = {k: v for k, v in locals().items() if v is not None}
  1. inspect's — link — signature and bind, which still requires would a list of the parameters
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    sig = signature(foo)
    sig_args = sig.bind(limit, offset, lower_bound, upper_bound).arguments
    magic_dict = {k: v for k, v in sig_args.items() if v is not None}

Other thoughts included making a class to make getattr available

It feels like I'm missing something obvious — feedback would be appreciated!


Someone suggested What is an elegant way to select all non-None elements from parameters and place them in a python dictionary?, whose responses are primarily "move to **kwargs". My initial reaction is that I would prefer to keep a specific list of arguments — is that bad logic by me? What is typical best practice with Python?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can try using decorators:

def capture(func):
    capture.kwds = None
    def wrap(*args, **kwargs):
        capture.kwds = kwargs
        return func(*args, **kwargs)
    return wrap
    
@capture
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    return None

Now you can call:

>>> foo(limit=1, offset=2, lower_bound=3, upper_bound=4)
None
>>> capture.kwds
{'limit': 1, 'offset': 2, 'lower_bound': 3, 'upper_bound': 4}
over 4 years ago · Santiago Trujillo Report

0

You can also use the locals method, but copy the locals at the top of your function. At the end one can use the keys of the original locals and select only those in the return statement:

def foo(a=None, b=None, c=None):
    original_locals = locals().copy()
    d = 'test' #Test adding new variable which should not be returned
    return {k:v for k,v in locals().items() if k in original_locals.keys() and v is not None}

foo(1)
>> {'a': 1}
foo(1, 2, 3)
>> {'a': 11, 'b': 2, 'c': 3}

Note that you have to copy the locals, otherwise this method will not work.

If you also want to add kwargs:

def func(a=None, b=None, c=None, **kwargs):
    org_loc = locals().copy()
    def check_kwargs(d):
        if 'kwargs' in d.keys():
            d.update(d['kwargs'])
            del d['kwargs']
    check_kwargs(org_loc)
    d = 'test'
    new_loc = locals()
    check_kwargs(new_loc)
    return {k:v for k,v in new_loc.items() if k in org_loc.keys() and v is not None}

Then:

func(1)
>> {'a':1}
func(1, test='test')
>> {'a': 1, 'test': 'test'}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!