Thank you all for the quick response! On Sun, Dec 30, 2018 at 10:39 AM Avi Gross <avigr...@verizon.net> wrote:
> I have my usual off the wall answer. > > OK, seriously. Not exactly an answer but perhaps an experiment. > > The question was how to have a non-named first argument to a function with > some form of default. > > As was pointed out, this does not fit well with being able to have python > gather all positional arguments after it as well as all keyword arguments. > > But bear with me. Say I want to have a way to signal that I want a default > for the first argument? > > An empty comma fails but try this: > > def hello(a, *n, **m) : > if a == None: a=5 > print(a) > print(*n) > print(**m) > > The above says "a" is required. It can be followed by any number of > positional args gathered into "n" and any number of keyword args gathered > into "m" > > But what if you define a sentinel to watch for such as None, in the above? > > If the first and only arg is None, it switches to the default of 5. > > >>> hello(None) > 5 > > Add a few more args and it properly takes it. > > >>> hello(1,2,3) > 1 > 2 3 > > Switch the first to None: > > >>> hello(None,2,3) > 5 > 2 3 > > The keywords don't work for print but no biggie. > > But is this only for None? What I say any negative arg is replaced by 5? > > def hello(a, *n, **m) : > if a < 0: a=5 > print(a) > print(*n) > > Seems to work fine: > > >>> hello(-666, 2, 3, 4) > 5 > 2 3 4 > > And I wonder if we can use the darn ellipsis for something useful? > > def hello(a, *n, **m) : > if a == ... : a=5 > print(a) > print(*n) > > >>> hello(1,2,3) > 1 > 2 3 > >>> hello(...,2,3) > 5 > 2 3 > >>> hello(...,2,...) > 5 > 2 Ellipsis > > OK, all kidding aside, is this helpful? I mean if you want a function where > you MUST give at least one arg and specify the first arg can be some odd > choice (as above) and then be replaced by a default perhaps it would be > tolerable to use None or an Ellipsis. > > Or on a more practical level, say a function wants an input from 1 to 10. > The if statement above can be something like: > > >>> def hello(a, *n, **m) : > if not (1 <= a <= 10) : a=5 > print(a) > print(*n) > > > >>> hello(1,2,3) > 1 > 2 3 > >>> hello(21,2,3) > 5 > 2 3 > >>> hello(-5,2,3) > 5 > 2 3 > >>> hello("infinity and beyond",2,3) > Traceback (most recent call last): > File "<pyshell#32>", line 1, in <module> > hello("infinity and beyond",2,3) > File "<pyshell#28>", line 2, in hello > if not (1 <= a <= 10) : a=5 > TypeError: '<=' not supported between instances of 'int' and 'str' > > As expected, it may take a bit more code such as checking if you got an int > but the idea may be solid enough. It is NOT the same as having a default > from the command line but it may satisfy some need. > > Other than that, I fully agree that the current python spec cannot support > anything like this in the function definition. > > Side note: To spare others, I sent Steven alone a deeper reply about ways > to > select random rows from a pandas DataFrame. I am still learning how pandas > works and doubt many others here have any immediate needs. > > > > > > > > > > -----Original Message----- > From: Tutor <tutor-bounces+avigross=verizon....@python.org> On Behalf Of > Steven D'Aprano > Sent: Saturday, December 29, 2018 6:02 AM > To: tutor@python.org > Subject: Re: [Tutor] Defining variable arguments in a function in python > > On Sat, Dec 29, 2018 at 11:42:16AM +0530, Karthik Bhat wrote: > > Hello, > > > > I have the following piece of code. In this, I wanted to make > > use of the optional parameter given to 'a', i.e- '5', and not '1' > > > > def fun_varargs(a=5, *numbers, **dict): > [...] > > > > fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333) > > > > How do I make the tuple 'number' contain the first element to be 1 and > not > 2? > > > You can't. Python allocates positional arguments like "a" first, and only > then collects whatever is left over in *numbers. How else would you expect > it to work? Suppose you called: > > fun_varargs(1, 2, 3) > > wanting a to get the value 1, and numbers to get the values (2, 3). And > then > immediately after that you call > > fun_varargs(1, 2, 3) > > wanting a to get the default value 5 and numbers to get the values (1, 2, > 3). How is the interpreter supposed to guess which one you wanted? > > If you can think of a way to resolve the question of when to give "a" > the default value, then we can help you program it yourself: > > > def func(*args, **kwargs): > if condition: > # When? > a = args[0] > numbers = args[1:] > else: > a = 5 # Default. > numbers = args > ... > > But writing that test "condition" is the hard part. > > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Regards, Karthik A Bhat _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor