This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get the cartesian product of a series of lists in Python
Suppose I have an array of length n, representing n variables, and a function f of n variables. I want to sum over f applied to all values of the n variables in some finite set (i.e. {0,1}). Conceptually, it would be something like
for x[1] in {0,1}:
for x[2] in {0,1}:
...
sum += f(x[1], ..., x[n])
but obviously you can't write this.
Is there a nice way to do it, say in Python? (For the particular case of values in {0,1}, I could just loop over binary representations of integers from 0 to 2^n-1, but I want a more general solution).
# f is a function
# K is a list of possible values your variable may take
# n is number of args that f takes
import itertools
def sum_of_f_over_K_n(f,K,n):
K_to_the_n = [K for i in xrange(n)]
return sum(map(lambda(x):f(*x),itertools.product(*K_to_the_n)))
some_list = [0,1] # where your variables come from
def sample_func(a,b,c,d,e):
return a or b or c or d or e
sum_of_f_over_K_n(sample_func, some_list, 5) == 2**5 -1
Related
This question already has answers here:
Python - fibonacci numbers [duplicate]
(4 answers)
How does swapping of members in tuples (a,b)=(b,a) work internally?
(1 answer)
Closed 3 years ago.
I've found a Python code of Fibonacci Generator, but don't understand all of it. Can some one explain a, b = b, a + b line in particulat?
a = int(input('Give amount: '))
def fib(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
print(list(fib(a))
How does it work?
This line of code works by creating a tuple, and then destructuring it to assign two variables at once. The result is that both a and b on the left-hand-side are assigned the results of expressions on the right-hand-side which are calculated using the original values of a and b.
The expression on the right-hand-side is b, a + b which is equivalent to (b, a + b), i.e. it creates a tuple with two components.
The assignment target on the left-hand-side is a, b which is equivalent to (a, b), i.e. it assigns to two variables simultaneously, using the values of the two components from the tuple respectively. This is called a destructuring assignment.
This is convenient because if the two assignments were written separately, as in the code below, then it would not have the desired effect. The first line changes a's value, and then the new value would (incorrectly) be used to calculate b:
# WRONG!
a = b
b = a + b
This question already has answers here:
Python: Generate random number between x and y which is a multiple of 5 [duplicate]
(4 answers)
Closed 3 years ago.
I want to generate a random number from range [a,b] that is dividsible by N (4 in my case).
I have the solution, but is there a better (more elegant) way to do it?
result = random.randint(a, b)
result = math.ceil(result / 4) * 4
Solutions from here:
Python: Generate random number between x and y which is a multiple of 5
doesn't answer my question since I'll have to implement something like:
random.randint(a, b) * 4;
I'll have to divide original range by 4 and it's less readable then my original solution
A generic solution and an example
import random
def divisible_random(a,b,n):
if b-a < n:
raise Exception('{} is too big'.format(n))
result = random.randint(a, b)
while result % n != 0:
result = random.randint(a, b)
return result
# get a random int in the range 2 - 12, the number is divisible by 3
print(divisible_random(2,12,3))
The first thing coming to my mind is creating a list of all the possible choices using range in the given interval, followed by randomly choosing one value using choice.
So, in this case, for a given a and b,
random.choice(range(a + 4 - (a%4), b, 4))
If a is a perfect multiple of 4, then
random.choice(range(a, b, 4))
Would give you the required random number.
So, in a single generic function, (as suggested in comments)
def get_num(a, b, x):
if not a % x:
return random.choice(range(a, b, x))
else:
return random.choice(range(a + x - (a%x), b, x))
where x is the number whose multiples are required.
As the others have pointed out, your solution might produce out of range results, e.g. math.ceil(15 / 4) * 4 == 16. Also, be aware that the produced distribution might be very far from uniform. For example, if a == 0 and b == 4, the generated number will be 4 in 80% of the cases.
Aside from that, it seems good to me, but in Python, you can also just use the integer division operator (actually floor division, so it's not equivalent to your examlpe):
result = random.randint(a, b)
result = result // 4 * 4
But a more general albeit less efficient method of generating uniform random numbers with specific constraints (while also keeping the uniform distribution) is generating them in a loop until you find a good one:
result = 1
while result % 4 != 0:
result = random.randint(a, b)
Use random.randrange with a step size of n, using a+n-(a%n) as start if a is non-divisible by n, else use a as start
import random
def rand_n(a, b,n):
#If n is bigger than range, return -1
if n > b-a:
return -1
#If a is divisible by n, use a as a start, using n as step size
if a%n == 0:
return random.randrange(a,b,n)
# If a is not divisible by n, use a+n-(a%n) as a start, using n as step size
else:
return random.randrange(a+n-(a%n),b, n)
This question already has answers here:
Python:How to make the sum of the values of a while loop store into a variable?
(4 answers)
Closed 3 months ago.
Basically i want to sum up the result of the expression k=5x+17 but with different x, like (k=53+17) + (k=5*4+17) and so on... so far my code looks like the following.The result needs to be Σ which goes from the range (3,9).
for x in range(3,9):
k=5*x+17
k+=k
print(k)
you're overwriting k at each iteration, so in the end the result is just (5*8+17)*2
To perform such a sum, with x varying between 3 and 8 (9 is not included) so it in a generator comprehension and pass the result to sum, you'll avoid the nasty side-effects like you just created.
result = sum(5*x+17 for x in range(3,9))
(of course if you want to include 9 you have to range from 3 to 10), so depending on the upper boundary, you get 267 or 329
You can also do that without using sum at all using the n*(n+1)//2 formula for sum of integers from 1 to n and adapting it a la project euler to reduce complexity:
start = 3
end = 9 # inclusive
result = ((end*(end+1))//2 - ((start-1)*(start))//2)*5 + (end-start+1)*17
Remembering that the sum of integers between 1 and n is n*(n+1)/2 and using some basic summation equalities, you can calculate the result directly:
>>> (3 + 9 - 1) * (9 - 3) // 2 * 5 + 17 * (9 - 3)
267
For a range from i to j and an expression a*x+b, you can do:
a*(j-i)*(i+j-1)//2 + b*(j-i)
Because what you want is:
Σax+b = aΣx + Σb
#Use this simple code
l=[]
for x in range(3,9):
y = lambda x :5*x+17
l.append(y(x))
l =sum(l)
print l
This question already has answers here:
counting combinations and permutations efficiently
(13 answers)
Closed 7 years ago.
How do I get a number of the possible combinations knowing the number of characters used in generating the combinations and a range of lengths.
To get all permutations i would use:
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
minLen = 1
maxLen = 3
total = 0
for i in range(minLen,maxLen+1):
total += len(chars)**i
How would I do this for combinations? When repetition is not allowed.
I'm sure there's a mathematical formula to do this but I couldn't find it anywhere.
Thanks!
EDIT:
I realised that code might not be readable so here's an explenation:
It's pretty obvious what the variables are: minimum combination length, maximum, used characters...
The for loop goes from 1 to 3 and each time it adds this to the total: length of characters (len(chars)) to the power of i (the current iteration's length).
This is a basic way of calculating permutations.
So, you actually need a way to count the Binomial coefficient, right?
import math
def binomial_cooefficient(n: int, k: int) -> int:
n_fac = math.factorial(n)
k_fac = math.factorial(k)
n_minus_k_fac = math.factorial(n - k)
return n_fac/(k_fac*n_minus_k_fac)
This might not be the most optimal implementation, but it works :)
I believe that you are looking for scipy.misc.comb (which gives you the number of unique combinations of a binomial (of the form of from N take X):
>>> from scipy.misc import comb
>>> comb(10, 1) # Num of unique combinations of *from 10 take 1*
10.0
>>> comb(10, 2) # Num of unique combinations of *from 10 take 2*
45.0
And so on.. You can then get a nice reduce:
>>> total_len = 10
>>> min_size = 1
>>> max_size = 2
>>> reduce(lambda acc, x: acc + comb(total_len, x), range(min_size, max_size+1), 0)
55.0
The above reduce is the 1-liner functional equivalent of your for:
>>> total = 0
for x in range(min_size, max_size+1):
total += comb(total_len, x)
As a side note, if you use comb(total_len, x, exact=True) you will get the result as an integer rather than a float.
This question already has an answer here:
Why is my function using Python time limited in input value magnatude?
(1 answer)
Closed 9 years ago.
I am trying to make a function that calculate the modular exponential MODEXP(a,e,p).
This function takes m and n as a parameters, where p is a prime number at most 2^m and e is 2^n and a is random number less than p.
Here is my code:
import random
def question_3(m,n):
list = []
i = 1
for i in range(2,2**m):
flag=True
for num in list:
if(i%num==0):
flag=False
if flag:
list.append(i)
p = choice(list)
a = randint(1,int(p)-1)
e = pow(2,n)
return pow(a, e, p)
question_3(5,5)
For m and n over 20, the code begins to hang. How do I prevent that?
If you just want to calculate
(modulus of a raised to the power e)modp
or something similar then
I would Highly recommend you this wiki article
In this case maximum number of iteration would be equal to number of bits in binary representation of variable e.