How to extract parameters from a list and pass them to a function call
You can unpack a tuple or a list into positional arguments using a star.
def add(a, b, c):
print(a, b, c)
x = (1, 2, 3)
add(*x)
Similarly, you can use double star to unpack a dict into keyword arguments.
x = { 'a': 3, 'b': 1, 'c': 2 }
add(**x)
Extract the elements of list as individual arguments within custom function in r
Is this what you're looking for? The crux is to wrap formals()
in list()
, and thus obtain a named list of all ("formal") parameters for testfunc()
.
My interpretation of your question is that you want to pass a named list as the x
parameter to testfunc()
, which contains named values to override other parameters passed to testfunc()
alongside x
. This list might be "incomplete", in that it does not necessarily name every other parameter (like cc
and ee
). Those that are not overridden are left as they are; unless they possess the default value of NULL
, in which case they are converted to 0
.
Using the formals()
as above, we can define a testfunc()
testfunc <- function(x, aa = NULL, bb = NULL, cc = NULL, dd = NULL, ee = NULL, ff = NULL) {
# Capture what values were passed to what parameters of 'testfunc()'.
params <- as.list(formals())
param_names <- names(params)
# For convenience, record the named variables listed under 'x'.
x_names <- names(x)
# Process each parameter (besides 'x' itself).
for(p_name in param_names[param_names != "x"]) {
# If the parameter is named in 'x', override it with the value from 'x'.
if(p_name %in% x_names) {
assign(p_name, x[[p_name]])
}
# Otherwise, leave the parameter alone...unless it is NULL and should be
# replaced with 0.
else if(is.null(get(p_name))) {
assign(p_name, 0)
}
}
# ...
# Any further operations; where parameters can be referenced like any other parameter
# in any other function, rather than having to be 'unlist'ed from 'x'.
# ...
# Explicitly name the parameters in the output list.
q <- list(
aa = aa,
bb = bb,
cc = cc,
dd = dd,
ee = ee,
ff = ff
)
return(q)
}
such that this call
test <- list(aa = 2, bb = 0.5, dd = 2, ff = 16)
testfunc(test)
yields the following list
as output:
$aa
[1] 2
$bb
[1] 0.5
$cc
[1] 0
$dd
[1] 2
$ee
[1] 0
$ff
[1] 16
Note
I have given priority to x
. That is, I have assumed you want to keep any NULL
s that were explicitly assigned by name in x
. So explicitly giving x
a NULL
element like aa
here
test <- list(aa = NULL, bb = 0.5, dd = 2, ff = 16)
testfunc(test)
will yield a NULL
for aa
in the output:
$aa
NULL
$bb
[1] 0.5
$cc
[1] 0
$dd
[1] 2
$ee
[1] 0
$ff
[1] 16
If you want to override this behavior, and ensure that any NULL
is replaced by 0
in the output, then simply change the else if
to an if
, in line 18 of the function definition:
# ...
if(is.null(get(p_name))) {
assign(p_name, 0)
}
# ...
Tips
Your original solution failed because you used !
is.null()
rather than is.null()
; so you avoided overriding any NULL
s with 0
.
If you were expecting unlist(x)
to populate the environment of testfunc()
with the contents of x
, you are sadly mistaken. All unlist()
does is "flatten" x
into a (homogenized) vector of its atomic components; so we get
x <- list(
a = 1,
list(
b = TRUE,
"hi"
)
)
unlist(x, recursive = TRUE, use.names = TRUE)
#> a b
#> "1" "TRUE" "hi"
homogenized into a (named) character
vector. Your code inertly returns this value and moves on.
Only with something like assign
("a", 1)
(and so forth) could you achieve the effect of actually populating these values as named variables in your environment.
Extracting Arguments from a Function Passed as a Parameter to Another Function in JavaScript
Here is a solution that only requires you to change the code in test
(with the exception of your call to test where I've replaced (isNumber, isNumber)
with [isNumber, isNumber]
).
You don't have to do anything special to get access to add
's arguments because you create the function inside test
and return it to be called by console.log(add(5, 6));
.
Using arguments
inside any function will give you the function's arguments as an array.
The ...
in func(... arguments);
is the spread operate which takes an array and expands it in place. See spread operator.
function test(precondition, postcondition, func) {
// Extract arguments of func which in this case should be 5 and 6
// This is required to check whether isNumber(5) and isNumber(6)
// both return true, so that precondition is met
return function() {
for (const i in arguments) {
const argi = arguments[i];
const precondition_i = precondition[i];
console.log('precondition['+i+'] met: ' + precondition_i(argi));
}
const r = func(... arguments);
console.log('postcondition met: ' + postcondition(r));
return r;
};
}
var add = test([isNumber, isNumber], isNumber, function add(x, y) {return x+y; });
console.log(add(5, 6));
Or a less generic solution that doesn't use arguments
and ...
and doesn't pass in an array as precondition
:
function test(precondition, postcondition, func) {
// Extract arguments of func which in this case should be 5 and 6
// This is required to check whether isNumber(5) and isNumber(6)
// both return true, so that precondition is met
return function(x, y) {
console.log('precondition met for x: ' + precondition(x));
console.log('precondition met for y: ' + precondition(y));
const r = func(x, y);
console.log('postcondition met: ' + postcondition(r));
return r;
};
}
var add = test(isNumber, isNumber, function add(x, y) {return x+y; });
console.log(add(5, 6));
Call functions on elements of list
You can use *
to unpack the values in your list as parameters of your function:
def f(a, b, c):
print(a,b,c)
x = [4, 6, 10]
f(*x)
Output:
4 6 10
Just be careful that your list has the proper number of parameters.
Extracting a parameter from a function passed as parameter
What you already have is the correct (and only) way to approach this situation in C++Builder's "classic" (pre-C++11) compilers.
In order to support a variable number of parameters, you will have to use multiple overloads, there is no other option (without delving into low-level inline assembly to setup call stacks manually, but even then it may not work correctly across thread boundaries), eg:
void Class1::MainThreadFunction()
{
if (GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction);
return;
}
//...
}
void Class1::MainThreadFunction(const __int64 param)
{
if(GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction, param);
return;
}
//...
}
// and so on as needed ...
template<typename FuncType>
void Class2::RunInMainThread(FuncType FuncToCall)
{
struct {
FuncType F;
void __fastcall FTC() { F(); }
} Args = {FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType param)
{
struct {
const ParamType &P;
FuncType F;
void __fastcall FTC() { F(P); }
} Args = {param, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType1, typename ParamType2>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType1 param1, const ParamType2 param2)
{
struct {
const ParamType1 &P1;
const ParamType2 &P2;
FuncType F;
void __fastcall FTC() { F(P1, P2); }
} Args = {param1, param2, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
// and so on as needed...
If you look through various RTL header files, such as sysvari.h
and utilcls.h
, using overloads is how Borland itself approaches the issue of variable number of parameters in several of its own APIs, sometimes upwards of 30+ parameters, which is more than enough to handle most user code.
Pass a list to a function to act as multiple arguments
function_that_needs_strings(*my_list) # works!
You can read all about it here: Unpacking Argument Lists - The Python Tutorial
Calling Python function with set of parameters from variable
You can use *args
or **kwargs
. The names args
and kwargs
don't actually matter, but its the *
and **
that does the trick. Basically, *
will unpack a list, and similarly, **
will unpack a dict.
*args
is just a list of values in the same order as where you defined your function.
eg.
args = [23, 6, 2, "label", 5, 25, 21, 343.22, 111.34, 2]
write2db(*args)
**kwargs
is a key-value mapping (python dict) of argument names to argument values
eg.
kwargs = {
'pocnr': 23,
'larm1': 21,
# ... etc.
}
write2db(**kwargs)
Extract parameter values of a function passed into parameter of function
compile_name <- function(first_name, last_name){
paste(first_name, last_name)
}
convert_call_to_list <- function(x) {
if (is.call(x)) as.list(x) else x
}
create_project <- function(project_name,...) {
first_pass <- as.list(match.call())
second_pass <- lapply(first_pass, convert_call_to_list)
setNames(second_pass, names(first_pass))
}
create_project(project_name = compile_name(first_name = "first", last_name = "last"), more_stuff = "more")
#> [[1]]
#> create_project
#>
#> $project_name
#> $project_name[[1]]
#> compile_name
#>
#> $project_name$first_name
#> [1] "first"
#>
#> $project_name$last_name
#> [1] "last"
#>
#>
#> $more_stuff
#> [1] "more"
Created on 2019-02-27 by the reprex package (v0.2.1)
How to get parameters from data list with 'for' cycle
A list
should be created using squared bracket []
instead of curly bracket {}
used by set
and dictionary
.
For your question you should be able to achieve it using the code snippet as follow
for i in list:
function(*i)
The *
operator unpacks the tuple in the list and provides it as parameter for the function
Related Topics
Multiple Levels of 'Collection.Defaultdict' in Python
Special (Magic) Methods in Python
Split List into Smaller Lists (Split in Half)
Python Method for Reading Keypress
Import Error: No Module Named Numpy
Selecting from Multi-Index Pandas
How to Make Two Plots Side-By-Side Using Python
Is There a Clever Way to Pass the Key to Defaultdict's Default_Factory
Getting the Caller Function Name Inside Another Function in Python
What Is the Fastest Way to Parse Large Xml Docs in Python
Sqlalchemy: What's the Difference Between Flush() and Commit()
Python Pandas Extract Year from Datetime: Df['Year'] = Df['Date'].Year Is Not Working
Running Get_Dummies on Several Dataframe Columns
Dynamic Terminal Printing with Python
What Do I Use for a Max-Heap Implementation in Python
Configuring Spark to Work with Jupyter Notebook and Anaconda