l have the following input list composed of values which varies from k=0 to 4:
vector_input= [(3, 3, 3, 3, 3), (0, 0, 1), (3, 4, 3, 3, 4, 4), (1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 3, 3, 3, 1, 1, 3), (0, 0), (4, 4, 4, 4, 4), (1, 1), (3, 3), (1, 4, 3, 2), (3, 3, 4, 4, 4), (4, 4, 4, 4, 4), (3,), (2, 2), (2, 2, 2, 2, 2, 2), (0, 0, 0, 0, 1, 0), (1, 1, 1, 1, 1), (1, 1, 1, 1, 1), (0, 0, 0, 0, 0, 0, 1, 0, 0, 1)]
l want to transform this list into a list of frequency output of dimension of k (k=4) so that to get list output as follows :
vector_output=[
[0,0,0,5,0],[2,1,0,0,0],[0,0,0,3,3],[0,4,0,0,0],[0,16,0,0,0], [0,3,0,4,0],
[2,0,0,0,0],[0,0,0,0,5],[0,0,0,3,0],[0,0,2,0,0],[0,0,6,0,0],[5,1,0,0,0],[0,5,0,0,0],[0,5,0,0,0],[8,2,0,0,0]]
For instance : (3, 3, 3, 3, 3) becomes (0,0,0,5,0) because three is repeated five times and 0,1,2,4 zero times.
You could create a distribution function:
def distribution(vector, highest=5):
dist = [0] * highest
for i in vector:
dist[i] += 1
return dist
and apply it to every vector with a list comprehension:
vector_input= [(3, 3, 3, 3, 3), (0, 0, 1), (3, 4, 3, 3, 4, 4), (1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 3, 3, 3, 1, 1, 3), (0, 0), (4, 4, 4, 4, 4), (1, 1), (3, 3), (1, 4, 3, 2), (3, 3, 4, 4, 4), (4, 4, 4, 4, 4), (3,), (2, 2), (2, 2, 2, 2, 2, 2), (0, 0, 0, 0, 1, 0), (1, 1, 1, 1, 1), (1, 1, 1, 1, 1), (0, 0, 0, 0, 0, 0, 1, 0, 0, 1)]
print([distribution(v) for v in vector_input])
# [[0, 0, 0, 5, 0], [2, 1, 0, 0, 0], [0, 0, 0, 3, 3], [0, 4, 0, 0, 0], [0, 16, 0, 0, 0], [0, 3, 0, 4, 0], [2, 0, 0, 0, 0], [0, 0, 0, 0, 5], [0, 2, 0, 0, 0], [0, 0, 0, 2, 0], [0, 1, 1, 1, 1], [0, 0, 0, 2, 3], [0, 0, 0, 0, 5], [0, 0, 0, 1, 0], [0, 0, 2, 0, 0], [0, 0, 6, 0, 0], [5, 1, 0, 0, 0], [0, 5, 0, 0, 0], [0, 5, 0, 0, 0], [8, 2, 0, 0, 0]]
You can try this:
import itertools
vector_input= [(3, 3, 3, 3, 3), (0, 0, 1), (3, 4, 3, 3, 4, 4), (1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 3, 3, 3, 1, 1, 3), (0, 0), (4, 4, 4, 4, 4), (1, 1), (3, 3), (1, 4, 3, 2), (3, 3, 4, 4, 4), (4, 4, 4, 4, 4), (3,), (2, 2), (2, 2, 2, 2, 2, 2), (0, 0, 0, 0, 1, 0), (1, 1, 1, 1, 1), (1, 1, 1, 1, 1), (0, 0, 0, 0, 0, 0, 1, 0, 0, 1)]
full_listing = list(set(itertools.chain(*vector_input)))
final_data = [tuple(list(b).count(c) for c in range(min(full_listing), max(full_listing)+1)) for b in vector_input]
Output:
[(0, 0, 0, 5, 0), (2, 1, 0, 0, 0), (0, 0, 0, 3, 3), (0, 4, 0, 0, 0), (0, 16, 0, 0, 0), (0, 3, 0, 4, 0), (2, 0, 0, 0, 0), (0, 0, 0, 0, 5), (0, 2, 0, 0, 0), (0, 0, 0, 2, 0), (0, 1, 1, 1, 1), (0, 0, 0, 2, 3), (0, 0, 0, 0, 5), (0, 0, 0, 1, 0), (0, 0, 2, 0, 0), (0, 0, 6, 0, 0), (5, 1, 0, 0, 0), (0, 5, 0, 0, 0), (0, 5, 0, 0, 0), (8, 2, 0, 0, 0)]
Related
I am trying to modify the code provided as answer by Hilberts in below question to allow it for multiple values and not only binary.
All binary combinations in a 2d Numpy
So, rather than only allow 0 and 1 like in the previous example, i would like find all combinations without rotations for data like 0, 1, 2 and 3 .
I modified it in this way, mainly replacing the "2" in the original code by a variable and tried to replace it by the variable "m" to follow the initial formula. But I think the issue here is related to the numpy type of data "bitwise_and" . Does anyone have any advices about what would be problem or any hint?
def get_binary_mats(n,m):
# all possible n by n binary matrices up to rotation:
bin_mats = (np.bitwise_and(np.arange(m**(n*n))[:,None], m ** np.arange(n*n)) > 0)\
.reshape(-1, n, n)
# define a score for each matrix based on position of ones
score = m ** np.arange(n*n).reshape(n,n)
# array([[ 1, 2, 4],
# [ 8, 16, 32],
# [ 64, 128, 256]])
score_arr = np.stack([np.rot90(score, k=k) for k in range(4)])
# array([[[ 1, 2, 4],
# [ 8, 16, 32],
# [ 64, 128, 256]],
# [[ 4, 32, 256],
# [ 2, 16, 128],
# [ 1, 8, 64]],
# [[256, 128, 64],
# [ 32, 16, 8],
# [ 4, 2, 1]],
# [[ 64, 8, 1],
# [128, 16, 2],
# [256, 32, 4]]])
scores = np.einsum("ijk,ljk->il", bin_mats, score_arr)
_, idx = np.unique(scores.min(1), return_index=True)
return bin_mats[idx,...]
Thank you
from itertools import combinations_with_replacement as combn
list(combn([0,1,2,3], 4))
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 0, 2),
(0, 0, 0, 3),
(0, 0, 1, 1),
(0, 0, 1, 2),
(0, 0, 1, 3),
(0, 0, 2, 2),
(0, 0, 2, 3),
(0, 0, 3, 3),
(0, 1, 1, 1),
(0, 1, 1, 2),
(0, 1, 1, 3),
(0, 1, 2, 2),
(0, 1, 2, 3),
(0, 1, 3, 3),
(0, 2, 2, 2),
(0, 2, 2, 3),
(0, 2, 3, 3),
(0, 3, 3, 3),
(1, 1, 1, 1),
(1, 1, 1, 2),
(1, 1, 1, 3),
(1, 1, 2, 2),
(1, 1, 2, 3),
(1, 1, 3, 3),
(1, 2, 2, 2),
(1, 2, 2, 3),
(1, 2, 3, 3),
(1, 3, 3, 3),
(2, 2, 2, 2),
(2, 2, 2, 3),
(2, 2, 3, 3),
(2, 3, 3, 3),
(3, 3, 3, 3)]
Hi guys i have this problem:
I have a list with number
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
Every time i found 0 i need to count it and know his position, but when the 0 is consecutive it count as one, for example:
Position start 5, Position end 8, Count 1
Position start 12, Position end 12, Count 2
Position start 14, Position end 14, Count 3
Position start 26, Position end 31, Count 4
This can be solved like this
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
last_was_0=False
zero_clusters=[]
for i in range(len(a)):
b=a[i]
if b==0:
if last_was_0:
zero_clusters[-1][-1]+=1
else:
zero_clusters.append([i, i])
last_was_0 = b==0
for i in range(len(zero_clusters)):
print(f'Position start {zero_clusters[i][0]}, Position end {zero_clusters[i][1]}, Count {i+1}')
but if i want to try it on two list? So doing the same thing that i do with one list but having two, and checking if the current index(the same for the two list) if are both 0
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
b= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
How can I achive the result?
I have already tried like this but it gives me as result only the first iteraction
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
b= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
last_was_0=False
zero_clusters=[]
for i in range(len(a)):
b=a[i]
c=b[i]
if b==0 and c==0:
if last_was_0:
zero_clusters[-1][-1]+=1
else:
zero_clusters.append([i, i])
last_was_0 = b==0
for i in range(len(zero_clusters)):
print(f'Position start {zero_clusters[i][0]}, Position end {zero_clusters[i][1]}, Count {i+1}')
Can someone help me achieve the same result of one list but with two??
You can iterate over the lists together uzing zip, and then use itertools groupby to group consecutive values.
Looping over that and storing the indexes where the key of the group is (0,0) will get you the result you want.
from itertools import groupby
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
b= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
zero_cluster = []
i = 0
for g, d in groupby(zip(a,b)):
data = list(d)
if g!=(0,0):
i+=len(data)
else:
zero_cluster.append((i, i+len(data)-1))
i+=len(data)
for i, cluster in enumerate(zero_cluster):
print(f'Position start {cluster[0]}, Position end {cluster[1]}, Count {i+1}')
Output
Position start 5, Position end 8, Count 1
Position start 12, Position end 12, Count 2
Position start 14, Position end 14, Count 3
Position start 16, Position end 16, Count 4
Position start 28, Position end 33, Count 5
Position start 36, Position end 36, Count 6
Position start 38, Position end 38, Count 7
Position start 40, Position end 40, Count 8
Also it might be helpful to understand what itertools groupby is doing by looking at this:
for g, d in groupby(zip(a,b)):
print(g,list(d))
Prints
(1, 1) [(1, 1), (1, 1), (1, 1), (1, 1), (1, 1)]
(0, 0) [(0, 0), (0, 0), (0, 0), (0, 0)]
(1, 1) [(1, 1), (1, 1), (1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1)]
(0, 0) [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
(1, 1) [(1, 1), (1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1)]
(0, 0) [(0, 0)]
(1, 1) [(1, 1)]
a numpy version
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
import numpy as np
def get_clusters(lst):
arr=np.array(lst)
diff=arr[:-1]-arr[1:]
starts = np.where(diff==1)
ends = np.where(diff==-1)
indices = np.vstack((starts[0]+1, ends[0])).T
return indices, diff[diff==1].size
print(get_clusters(a))
output
(array([[ 5, 8],
[12, 12],
[14, 14],
[16, 16],
[28, 33],
[36, 36],
[38, 38],
[40, 40]]), 8)
zip() is your friend when you need to compare elements of a list with it's predecessor or successor.
So you can use zip to get the starting index of each cluster of 1s and 0s. Then use zip again to combine these indexes into ranges of positions, selecting only the ranges that contain zeros.
a= [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
breaks = [i for i,(n,m) in enumerate(zip(a,a[1:]),1) if n!=m ]
positions = [ (s,e-1) for s,e in zip([0]+breaks,breaks+[len(a)]) if not a[s] ]
count = sum(e-s+1 for s,e in positions)
print(positions)
[(5, 8), (12, 12), (14, 14), (16, 16), (28, 33), (36, 36), (38, 38), (40, 40)]
print(count)
16
For two lists, you can combine them (using zip again) and apply the same solution:
x= [1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
y= [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]
a = [ paired != (0,0) for paired in zip(x,y) ]
breaks = [i for i,(n,m) in enumerate(zip(a,a[1:]),1) if n!=m ]
positions = [ (s,e-1) for s,e in zip([0]+breaks,breaks+[len(a)]) if not a[s] ]
count = sum(e-s+1 for s,e in positions)
print(positions)
[(5, 8), (12, 12), (14, 14), (16, 16), (28, 33), (36, 36), (38, 38), (40, 40)]
print(count)
16
If you're okay with using a library, this can be somewhat shortened using groupby from itertools:
from itertools import groupby
positions = [ (lg[0],lg[-1])
for bit,g in groupby(range(len(a)),lambda i:a[i]) if not bit
for lg in [list(g)]]
count = sum(e-s+1 for s,e in positions)
I want to place three numbers [0,1,-1] at 6 positions. It should give 3^6 = 729 combinations. The code should return something like:
(0,0,0,0,0,0)
(0,0,0,0,0,1)
(0,0,0,0,0,-1)
(0,0,0,0,1,1)
(0,0,0,0,1,-1)
.
.
(-1,-1,-1,-1,-1,0)
(-1,-1,-1,-1,-1,-1)
I tried using "itertools.permutations", but am confused about how to incorporate 0,1,-1 into it.
Check out itertools.product(*iterables, repeat=1) here.
Use like:
> product([-1, 0, 1], repeat=6)
[...]
(1, 1, 1, 0, -1, -1),
(1, 1, 1, 0, -1, 0),
(1, 1, 1, 0, -1, 1),
(1, 1, 1, 0, 0, -1),
(1, 1, 1, 0, 0, 0),
(1, 1, 1, 0, 0, 1),
(1, 1, 1, 0, 1, -1),
(1, 1, 1, 0, 1, 0),
(1, 1, 1, 0, 1, 1),
(1, 1, 1, 1, -1, -1),
(1, 1, 1, 1, -1, 0),
(1, 1, 1, 1, -1, 1),
(1, 1, 1, 1, 0, -1),
(1, 1, 1, 1, 0, 0),
(1, 1, 1, 1, 0, 1),
(1, 1, 1, 1, 1, -1),
(1, 1, 1, 1, 1, 0),
(1, 1, 1, 1, 1, 1)]
Gets you len(list(product([-1, 0, 1], repeat=6))) = 729
Use itertools.product
import iertools
assert(sum(1 for _ in itertools.product([-1, 0, 1], repeat=6)) == 3**6)
If you know itertools.permutations I think no more explanation is required.
For a list of numerical values of n length, e. g. [1, 3, 1, 2, ...], I would like to create a list of the lists of all possible combinations of values from range[x+1] where x is a value from the list. The output might look something like this:
for list[1, 3, 2] return all possible lists of range[x+1] values:
# the sequence of the list is unimportant
[
[0,0,0],[1,0,0],[0,1,0],[0,2,0],[0,3,0],[0,0,1],[0,0,2],[1,1,0],
[1,2,0],[1,3,0],[1,0,1],[1,0,2],[0,1,1],[0,2,1],[0,3,1],[0,1,2],
[0,2,2],[0,3,2],[1,1,1],[1,2,1],[1,3,1],[1,1,2],[1,2,2],[1,3,2]
]
So in this example I am looking for all variations of [e1, e2, e3] from e1 in [0,1], e2 in [0,1,2,3] and e3 in [0,1,2]
Use itertools.product with a dynamically-specified list of iterators:
vals = [1,3,2]
for item in itertools.product(*[range(x+1) for x in vals]):
print item
Output:
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(0, 2, 0)
(0, 2, 1)
(0, 2, 2)
(0, 3, 0)
(0, 3, 1)
(0, 3, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
(1, 2, 0)
(1, 2, 1)
(1, 2, 2)
(1, 3, 0)
(1, 3, 1)
(1, 3, 2)
Python's itertools module has a tool that does what you need:
import itertools
p = itertools.permutations([0, 1, 2, 3])
p_as_list = list(p)
Edit: As your needs are fairly specific you could benefit from having your own function that does something alike this one: (note I haven't got the implementation down just yet, maybe someone might refine this):
def magic_permutations (*args):
lists = []
larg = len(args)
for i in range(larg):
lists.append([])
i = 0
for nums in args:
for num in nums:
if i >= larg:
i = 0
lists[i].append(num)
i += 1
return lists
Edit: I misunderstood your question the first time, so I'll apologize for that. I'll however leave this be.
To obtain the exact sequence shown in the question (albeit in a different order, but that's not a problem) use this function:
import itertools as it
def combs(lst):
return [list(e) for e in it.product(*(range(x+1) for x in lst))]
The result is as expected:
combs([1, 3, 2])
=> [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2],
[0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 3, 0], [0, 3, 1], [0, 3, 2],
[1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2],
[1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 3, 0], [1, 3, 1], [1, 3, 2]]
for ii in itertools.product(range(2),range(4),range(3):
print ii
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(0, 2, 0)
(0, 2, 1)
(0, 2, 2)
(0, 3, 0)
(0, 3, 1)
(0, 3, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
(1, 2, 0)
(1, 2, 1)
(1, 2, 2)
(1, 3, 0)
(1, 3, 1)
(1, 3, 2)
It's not in the same order, but I think this is what you wanted:
def xrangeCombinations(input):
if len(input) > 1:
for i in xrange(input[-1] + 1):
for j in xrangeCombinations(input[:-1]):
yield j + [i]
else:
for i in xrange(input[-1] + 1):
yield [i]
for i in xrangeCombinations([1, 3, 2]):
print i
Produces the output:
[0, 0, 0]
[1, 0, 0]
[0, 1, 0]
[1, 1, 0]
[0, 2, 0]
[1, 2, 0]
[0, 3, 0]
[1, 3, 0]
[0, 0, 1]
[1, 0, 1]
[0, 1, 1]
[1, 1, 1]
[0, 2, 1]
[1, 2, 1]
[0, 3, 1]
[1, 3, 1]
[0, 0, 2]
[1, 0, 2]
[0, 1, 2]
[1, 1, 2]
[0, 2, 2]
[1, 2, 2]
[0, 3, 2]
[1, 3, 2]
This solution might be slower than alternatives so if speed is an issue you should probably improve it.
Using numpy if you don't mind getting tuples in the end:
>>> import numpy as np
>>> e1=np.array([0,1])
>>> e2=np.array([0,1,2])
>>> e3=np.array([0,1,2,3])
>>> g=np.meshgrid(e1,e2,e3) #you need numpy ver>1.7.0, change the order of final result by changing the order of e1, e2, e3
>>> zip(*[item.flatten() for item in g])
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 2, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3)]
I am trying to understand how to write code that will output all the divisors of a number. The approach that I am most interested in taking begins with a function that returns a dictionary where the keys are the prime divisors and the values are the number of times divisible. I have already written this function like so:
def div_pair(num):
divPair = {}
for prime in prime_gen():
primeDegree = 0
while num % prime == 0:
num = int(num / prime)
primeDegree += 1
if primeDegree > 0:
divPair[prime] = primeDegree
if num == 1:
return divPair
As an example, the number 84,000 outputs the dictionary
{2: 5, 3: 1, 5: 3, 7: 1}
What I want to do from here is generate powersets(?) of any given values returned by the different numbers divPair would return, and then multiply these powersets by their matched primes. This is an example which uses the kind of code I am trying to use to generate the powersets:
from itertools import product
list(product(range(5+1), range(1+1), range(3+1), range(1+1)))
Outputs this:
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 1, 0),
(0, 0, 1, 1),
(0, 0, 2, 0),
(0, 0, 2, 1),
(0, 0, 3, 0),
(0, 0, 3, 1),
(0, 1, 0, 0),
(0, 1, 0, 1),
(0, 1, 1, 0),
(0, 1, 1, 1),
(0, 1, 2, 0),
(0, 1, 2, 1),
(0, 1, 3, 0),
(0, 1, 3, 1),
(1, 0, 0, 0),
(1, 0, 0, 1),
(1, 0, 1, 0),
(1, 0, 1, 1),
(1, 0, 2, 0),
(1, 0, 2, 1),
(1, 0, 3, 0),
(1, 0, 3, 1),
(1, 1, 0, 0),
(1, 1, 0, 1),
(1, 1, 1, 0),
(1, 1, 1, 1),
(1, 1, 2, 0),
(1, 1, 2, 1),
(1, 1, 3, 0),
(1, 1, 3, 1),
(2, 0, 0, 0),
(2, 0, 0, 1),
(2, 0, 1, 0),
(2, 0, 1, 1),
(2, 0, 2, 0),
(2, 0, 2, 1),
(2, 0, 3, 0),
(2, 0, 3, 1),
(2, 1, 0, 0),
(2, 1, 0, 1),
(2, 1, 1, 0),
(2, 1, 1, 1),
(2, 1, 2, 0),
(2, 1, 2, 1),
(2, 1, 3, 0),
(2, 1, 3, 1),
(3, 0, 0, 0),
(3, 0, 0, 1),
(3, 0, 1, 0),
(3, 0, 1, 1),
(3, 0, 2, 0),
(3, 0, 2, 1),
(3, 0, 3, 0),
(3, 0, 3, 1),
(3, 1, 0, 0),
(3, 1, 0, 1),
(3, 1, 1, 0),
(3, 1, 1, 1),
(3, 1, 2, 0),
(3, 1, 2, 1),
(3, 1, 3, 0),
(3, 1, 3, 1),
(4, 0, 0, 0),
(4, 0, 0, 1),
(4, 0, 1, 0),
(4, 0, 1, 1),
(4, 0, 2, 0),
(4, 0, 2, 1),
(4, 0, 3, 0),
(4, 0, 3, 1),
(4, 1, 0, 0),
(4, 1, 0, 1),
(4, 1, 1, 0),
(4, 1, 1, 1),
(4, 1, 2, 0),
(4, 1, 2, 1),
(4, 1, 3, 0),
(4, 1, 3, 1),
(5, 0, 0, 0),
(5, 0, 0, 1),
(5, 0, 1, 0),
(5, 0, 1, 1),
(5, 0, 2, 0),
(5, 0, 2, 1),
(5, 0, 3, 0),
(5, 0, 3, 1),
(5, 1, 0, 0),
(5, 1, 0, 1),
(5, 1, 1, 0),
(5, 1, 1, 1),
(5, 1, 2, 0),
(5, 1, 2, 1),
(5, 1, 3, 0),
(5, 1, 3, 1)]
which is really the output that I want. I just need to modify the code to accept divPair.values() in some way. So I write this:
from itertools import product
divPair = div_pair(84000)
list(product(range(i+1) for i in divPair.values()))
which seems to me as if it should be correct, but it outputs this mess:
[(range(0, 6),), (range(0, 2),), (range(0, 4),), (range(0, 2),)]
and I can't figure out how to fix it. There is a post here which offers fantastic solutions to what I am trying to do. I am just trying to work toward them with what I know.
product returns the product of its arguments, and you have passed it a single one, the (range(i+1) for i in divPair.values()) generator. The generator yielded a list of range objects. That's like doing this:
>>> list(product(['range', 'range', 'range']))
[('range',), ('range',), ('range',)]
You have to pass your ranges as individual arguments.
Do this:
list(product(*[range(i+1) for i in divPair.values()]))
(or this)
list(product(*(range(i+1) for i in divPair.values())))