Whats the pythonic way to handle empty *args when creating a set?
Solution 1
Is there a way to pass an "entire set" argument to SubsetOutput
, so you can bury the conditional inside its call rather than have an explicit if
? This could be None
or []
, for example.
# Pass None to use full subset.
def Export(source, target, *args, sep=','):
for item in source:
SubsetOutput(WriteFlatFile(target), args or None).send(item[0])
# Pass an empty list [] to use full subset. Even simpler.
def Export(source, target, *args, sep=','):
for item in source:
SubsetOutput(WriteFlatFile(target), args).send(item[0])
If not, I would go with the two loop solution, assuming the loop really is a single line. It reads well and is a reasonable use case for a little bit of code duplication.
def Export(source, target, *args, sep=','):
if args:
for item in source:
SubsetOutput(WriteFlatFile(target), args).send(item[0])
else:
for item in source:
FullOutput(WriteFlatFile(target)).send(item[0])
Solution 2
Just check its not none, you don't have to create a separate argument
def test(*args):
if not args:
return #break out
return True #or whatever you want
Solution 3
How about this:
def MyFunc(argument, *args):
( DoSomething for i in (filter(args.__contains__ ,argument) if args else argument) )
justin cress
Updated on December 20, 2020Comments
-
justin cress over 3 years
Defining a function,
MyFunction(argument, *args): [do something to argument[arg] for arg in *args]
if *args is empty, the function doesn't do anything, but I want to make the default behavior 'use the entire set if length of *args == 0'
def Export(source, target, *args, sep=','): for item in source: SubsetOutput(WriteFlatFile(target), args).send(item[0])
I don't want to check the length of args on every iteration, and I can't access the keys of item in source until the iteration begins...
so i could
if len(args) != 0: for item in source: else for item in source:
which will probably work but doesn't seem 'pythonic' enough?
is this (is there) a standard way to approach *args or **kwargs and default behavior when either is empty?
More Code:
def __coroutine(func): """ a decorator for coroutines to automatically prime the routine code and method from 'curous course on coroutines and concurrency' by david beazley www.dabeaz.com """ def __start(*args, **kwargs): cr = func(*args, **kwargs) next(cr) return cr return __start def Export(source, target, *args, sep=','): if args: for item in source: SubsetOutput(WriteFlatFile(target, sep), args).send(item) else: for item in source: WriteFlatFile(target, sep).send(item) @__coroutine def SubsetOutput(target, *args): """ take *args from the results and pass to target TODO ---- raise exception when arg is not in result[0] """ while True: result = (yield) print([result.arg for arg in result.dict() if arg in args]) target.send([result.arg for arg in result.dict if arg in args]) @__coroutine def WriteFlatFile(target, sep): """ take set of results to a flat file TODO ---- """ filehandler = open(target, 'a') while True: result = (yield) line = (sep.join([str(result[var]) for var in result.keys()])).format(result)+'\n' filehandler.write(line)
-
justin cress over 13 yearsthe two loop solution seems to be the easiest to implement (in this case), though I guess I was just more concerned with the general case where the loop may not be a single line. Trying to avoid code repetition.
-
PatrickT almost 4 years"Just check it's not none" is an ambiguous statement, because if
args is None:
will not work, as*args
are set to()
. It must really beif not args:
(as your code states). So really your opening sentence ought to be "Just check it's not args" ! Thanks to your answer for helping me work that one out.