In a program I am writing at the moment I need to do the following:
if (x not in a) and (x not in b) and (x not in c):
which, of course, is very tedious, especially when a, b, and c all have much longer names.
Is there a built-in function that can do this:
if x is_in_one_of(a, b, c):
I know how I can do this with a function, and I am just wondering if there is a built-in way to do it.
Thanks in advance
You can do that as:
if all(x not in i for i in (a,b,c)):
The all above will only evaluate to True if x is not in any of a,b, or c
Or in other words:
if not any(x in i for i in (a,b,c)):
You asked for built-in ways of doing it but as you have it is very readable, albeit tedious to type. You could break onto a newline before each 'and'
For example (pep8 compliant)
if x not in a \
and x not in b \
and x not in c:
Alternatively, you could always use concatenation if appropriate
if x not in a + b + c:
Put it in a list
val = [a, b, c, d, e]
if x not in val:
do stuff
also this would work
if x not in [a, b, c]
Related
I have a function-object f, which takes 4 numeric inputs and outputs two numbers. Maybe
def f(a, b, c, d):
return a+b, c+d
or maybe
def f(a, b, c, d):
return a*c, d*c
To be clear, I don't actually know what f is, I just have it as an object.
I would like to create a new function-object, h, such that h(a,b,c,d)=x*c+y where (x,y)=f(a,b,c,d). The trouble is, I have no direct access to c, only to f.
def make_h(f):
???
return h
assert( make_h(f)(a,b,c,d) == f(a,b,c,d)[0]*c+f(a,b,c,d)[1])
Is it possible to do this in python? I have tried searching and reading some documentation, but have not found an answer (yet?).
EDIT: There is a simple answer (given below) when the signature of f is fixed. Suppose I had to do this to different functions, some with inputs (a, b, c, d), some with inputs (l, m, c), and maybe some with inputs (c, r). Would it still be possible to do what I want?
This example is strongly related to the concept of a decorator. My solution is the following:
def make_h(f):
def h(a, b, c, d):
x, y = f(a,b,c,d)
return x * c + y
return h
UPDATE. In case f has any number of arguments, we can use args, and kwargs. While it is a bad practice, if we know that one of kwargs is c, we could use the following code:
def make_h(f):
def h(*args, **kwargs):
x, y = f(*args, **kwargs)
return x * kwargs["c"] + y
return h
I am trying to write some code to perform a statistical test called model-reduction. Basically what I want to know is whether each variable in my function makes a meaningful contribution (i.e. significantly explains variance). Say for example my original fit-function looks like this:
full_model(x, a, b, c, d):
return a + b*x + c*x**3 + sin(d*x)
I want to compare reduced forms of this model. The once I need to check are:
reduced = lambda x, b, c, d: full_model(x, 0, b, c, d)
reduced = lambda x, a, c, d: full_model(x, a, 0, c, d)
reduced = lambda x, a, b, d: full_model(x, a, b, 0, d)
reduced = lambda x, a, b, c: full_model(x, a, b, c, 0)
For each case, I run some sort of test that I don't go into detail:
compare_models(full_model, reduced, x, y)
In reality, my fit function has more parameters, and I want test even further reduced functions. The code will be really messy if I have to explicitly define all possible models. Is there any way to define the reduced function in a for-loop? And is there any existing python module that can achieve what I want to do?
I would harness functools.partial for that following way, consider following simplified example:
import functools
def sum3(x, y, z):
return x+y+z
args = ["x", "y", "z"]
red_dict = {}
for arg in args:
red_dict[arg] = functools.partial(sum3, **{arg: 0})
print(red_dict["x"](y=10,z=10))
print(red_dict["y"](x=10,z=10))
print(red_dict["z"](x=10,y=10))
Output:
20
20
20
Explanation: args is list of args names you want to zero, in for-loop I use argument unpacking (**) to fix selected argument value to zero, then I store result in red_dict. Use loop is equivalent to doing:
red_dict["x"] = functools.partial(sum3, x=0)
red_dict["y"] = functools.partial(sum3, y=0)
red_dict["z"] = functools.partial(sum3, z=0)
This might be a basic question because I am still learning Python. But let's suppose I want to do something like this,
def add(a, b):
return a + b
a, b, c, d = 1, 2, 3, 4
sum = add(a, b if b == 2 else c, d)
Basically, I am trying to pass multiple functional args from inside a ternary operator(and I want a similar solution, if possible). This code currently gives the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes 2 positional arguments but 3 were given
What else have I tried:
add((a, b) if b == 2 else (c, d))
add(*(a, b) if b == 2 else *(c, d))
>>> add(*((a, b) if b == 2 else (c, d)))
3
As pointed out in the comments, the fact that you need so many parens to do this is a good sign that this is not a good way to structure this code.
what about
add(*(a, b) if b == 9 else (c, d))
It is similar to
add(*((a, b) if b == 9 else (c, d)))
sum_ = add(a, b) if b==2 else add(c, d)
above statement is equivalent to
sum_ = 0
if b==2:
sum_ = add(a, b)
else:
sum_ = add(c, d)
if in confusion, it is better to write a full statement, and then try to make it simple and in Turney.
Also, it's recommended, not to use the inbuilt function for the variable name
the problem is in the fucntion argument ,you declare a fucntion with 2 variable but you pass 3 ,what i inderstand you pass argument to funciton and it return the sum of the argument ,you can do this
def add(*args):
return sum(args)
a, b, c, d = 1, 2, 3, 4
value = add(a, b if b == 2 else c, d)
*don't declare sum as variable it is an an inbuilt function of python *
I am trying to define a function that will return true if two objects are connected and false otherwise.
In the example (cf. picture), where node a is connected to node b and c but there is no connection between b and c I want the function to behave like that:
connected(a, b) = true
connected(a, c) = true
connected(b, c) = false
So my question can be divided in two sub-questions:
a) How would i define such a function generally with the python api of Z3 (z3py), considering, that i would provide all possible assignments for the function upfront.
b) is it possible to define a funciton in a way, that I only provide the cases, where the function evaluates to true (i.e. only for the connected nodes) and then say somehow, that this function should evaluate to false in all other cases.
Sure:
from z3 import *
Object, (a, b, c) = EnumSort('Object', ('a', 'b', 'c'))
connections = [(a, b), (a, c)]
def isConnected(x, y):
return Or([And(x == i, y == j) for (i, j) in connections])
s = Solver()
s.add(isConnected(a, b))
s.add(isConnected(a, c))
print(s.check())
s.add(isConnected(b, c))
print(s.check())
The first print will say sat, and the second will say unsat, since b and c are not connected.
You can easily generalize this to any number of objects. Or even do things like:
s = Solver()
p = Const('p', Object)
q = Const('q', Object)
s.add(isConnected(p, q))
print(s.check())
print(s.model())
which will print:
sat
[q = b, p = a]
but note that this assignment will never contain the pair b, c as requested.
alias is right, you can simply declare the signature of the function and the implementation as you please. In other words, the evaluation of the function is up to you to assert.
I'm writing Python in functional style (I think what I'm getting at is similar to a monad?). Here's what I have so far, hardcoded for three functions. What if I had 10 or 100?
# a list of (function, function, function), each of which accept
# a scalar and return a list
funcs = [(lambda a: [a, a], lambda a: [a, a, a], lambda a: [a])] * 10
possible = []
car = 3
for a, b, c in funcs:
ra = a(car)
if ra:
rb = b(ra[0])
if rb:
rc = c(rb[0])
if rc: # last function
possible.extend(rc)
That is very monadic.
What you'd probably want to do is run a fold using the monad's bind function (using the Maybe or Either monad in this case), though your individual functions would have to return a monadic value (i.e. the list value you want returned by the original function wrapped in the monad's particular value constructor).
Your end call would be something like this (in a mix of Haskell and Python):
fold Maybe.bind Maybe.mreturn(car) funcs
(You'd want the Maybe.bind to be in a lambda probably since python doesn't do partial application like Haskell, I was just being lazy.)
Here's a python monad library/script to get you started.
Perhaps something like:
funcs = [(lambda a: [a, a], lambda a: [a, a, a], lambda a: [a])] * 10
initial = [3]
result = []
for function_chain on funcs:
running = initial
for function in function_chain:
running = function(running[0])
if not running[0]:
break
else:
result.extend(running)