Posts: 26
Threads: 13
Joined: Jul 2019
Jul-06-2021, 08:51 AM
(This post was last modified: Jul-06-2021, 08:51 AM by amjass12.)
Hi!
I don't think this should go in the code checking section as I am also asking for clarification on implementation so hope this thread is ok here.
I have a function that starts as follows:
def fun(*args):
list_args = []
for i in args:
list_args.append(i)
#continue with function then run:
fun(arg1, arg2, arg3, arg4)#say they are simply integers, 1,2,3,4
This works and does allow me to add a variable number of arguments and then continue downstream with the rest of the function definition.
My two question are:
1. is this valid and correct?
2. Reason for question, *args is specified as tuple - I know what tuples are, but not sure about what it means in this context.. does it prohibit the use of the *args in specific elements of code (say appending to a list as i have done)?
Would appreciate any clarification on what this actually means.
thank you!
Posts: 4,784
Threads: 76
Joined: Jan 2018
You can use args directly. It is indeed a tuple, which is created when the function is called
>>> def func(*args):
... print(args)
...
>>> func(1, 2, 3, 4)
(1, 2, 3, 4)
>>> Sometimes one needs to convert it to a list, it can be done faster this way
def func(*args):
args_list = list(args)
....
Posts: 26
Threads: 13
Joined: Jul 2019
(Jul-06-2021, 08:53 AM)Gribouillis Wrote: You can use args directly. It is indeed a tuple, which is created when the function is called
>>> def func(*args):
... print(args)
...
>>> func(1, 2, 3, 4)
(1, 2, 3, 4)
>>> Sometimes one needs to convert it to a list, it can be done faster this way
def func(*args):
args_list = list(args)
....
thank you! this makes sense, I didn't know *args was converted directly to a tuple object inside the function. Which then leads to another question which is, is it safer to iterate of a tuple or a list? As tuples are immutable its likely safer, but i dont know if its safer.
I generate a for loop to compare one value to each element of the newly created list from *args - i suppose it doesn't make a difference since nothing is being done to the list itself apart from saying compare value x to element 1, do something.. then compare to element 2, do something etc.
Posts: 4,784
Threads: 76
Joined: Jan 2018
Iterating a tuple or a list are equaly safe unless you try to update the structure during the iterations. Doing so with a tuple raises an exception because the tuple is immutable while doing so with a list yields unpredictable results. Most of the time you won't need to convert args to a list because you can read the arguments directly with expressions such as args[1] or perhaps x, y = args[:2] , etc.
Posts: 26
Threads: 13
Joined: Jul 2019
(Jul-06-2021, 09:23 AM)Gribouillis Wrote: Iterating a tuple or a list are equaly safe unless you try to update the structure during the iterations. Doing so with a tuple raises an exception because the tuple is immutable while doing so with a list yields unpredictable results. Most of the time you won't need to convert args to a list because you can read the arguments directly with expressions such as args[1] or perhaps x, y = args[:2] , etc.
got it! thank you so much this very clear!
And yes, that is how i iterate over the lists when carrying out the comparisons either for i in list: or when doing individually, list[1], list[2] etc..
Posts: 8,156
Threads: 160
Joined: Sep 2016
cross posted at https://stackoverflow.com/q/68269203/4046632
Please, don't cross-post or if you do so - provide a link.
Posts: 26
Threads: 13
Joined: Jul 2019
Jul-06-2021, 11:34 AM
(This post was last modified: Jul-06-2021, 11:35 AM by amjass12.)
(Jul-06-2021, 10:58 AM)buran Wrote: cross posted at https://stackoverflow.com/q/68269203/4046632
Please, don't cross-post or if you do so - provide a link.
this is weird - this has been copied and pasted..
the user that posted this is not me... i posted this here this morning and nowhere else. also- this has been asked 44mins ago - WELL after I asked and also got an answer 2 hours ago!
Posts: 6,780
Threads: 20
Joined: Feb 2020
This means the same in all contexts:
Quote:2. Reason for question, *args is specified as tuple - I know what tuples are, but not sure about what it means in this context.. does it prohibit the use of the *args in specific elements of code (say appending to a list as i have done)?
When used as below, args is a tuple and it has all the features and limitations of a tuple. likewise kwargs is a dictionary and it works exactly like a dictionary.
def func(*args, **kwargs):
kwargs['this is'] = 'a bad idea'
print(type(args), args, type(kwargs), kwargs)
func() Output: <class 'tuple'> () <class 'dict'> {'this is': 'a bad idea'}
So you can do anything with args that you can do with a tuple, and since args is a tuple you cannot append things to args.
def func(*args):
augmented_args = [1, 2, 3]
augmented_args.extend(args)
print(augmented_args)
args.append('Not allowed')
func(4, 5, 6) Output: [1, 2, 3, 4, 5, 6]
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk.py", line 7, in <module>
func(4, 5, 6)
File "c:\Users\hystadd\Documents\python\sandbox\junk.py", line 5, in func
args.append('Not allowed')
AttributeError: 'tuple' object has no attribute 'append'
Posts: 8,156
Threads: 160
Joined: Sep 2016
(Jul-06-2021, 11:34 AM)amjass12 Wrote: this is weird - this has been copied and pasted..
OK, I agree. It's really weird.
I checked all three questions asked by this SO user and all of them were copy/paste verbatim from threads here (by different users).
I will revoke the warning for cross-posting
Posts: 26
Threads: 13
Joined: Jul 2019
(Jul-06-2021, 06:29 PM)deanhystad Wrote: This means the same in all contexts:
Quote:2. Reason for question, *args is specified as tuple - I know what tuples are, but not sure about what it means in this context.. does it prohibit the use of the *args in specific elements of code (say appending to a list as i have done)?
When used as below, args is a tuple and it has all the features and limitations of a tuple. likewise kwargs is a dictionary and it works exactly like a dictionary.
def func(*args, **kwargs):
kwargs['this is'] = 'a bad idea'
print(type(args), args, type(kwargs), kwargs)
func() Output: <class 'tuple'> () <class 'dict'> {'this is': 'a bad idea'}
So you can do anything with args that you can do with a tuple, and since args is a tuple you cannot append things to args.
def func(*args):
augmented_args = [1, 2, 3]
augmented_args.extend(args)
print(augmented_args)
args.append('Not allowed')
func(4, 5, 6) Output: [1, 2, 3, 4, 5, 6]
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk.py", line 7, in <module>
func(4, 5, 6)
File "c:\Users\hystadd\Documents\python\sandbox\junk.py", line 5, in func
args.append('Not allowed')
AttributeError: 'tuple' object has no attribute 'append'
thank you - so the solution to manipulating the tuple of variable arguments would be to say make a list etc as others have suggested - i know it seems silly.. but one thing i wasn't sure of was if this 'pythonic' and 'allowed'
|