How can I create a table with 64 combinations with python? - python
I want to create a table that one column is choosing 3 out of a list [1,2,3,4] randomly with replacement. Then another column is only changing the middle number.
For example,
column 1 column2
111 121
111 131
111 141
121 111
121 131
...
444 414
444 424
444 434
The total should be 64 combinations. I tried combinations_with_replacement()
lst = [1,2,3,4]
ref = list(it.combinations_with_replacement(lst, 3))
>>> print(ref)
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 3), (1, 3, 4), (1, 4, 4), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 3), (2, 3, 4), (2, 4, 4), (3, 3, 3), (3, 3, 4), (3, 4, 4), (4, 4, 4)]
>>> len(ref)
20
but it did not work as I wanted... Any suggestions on how to change?
Thanks
Just as a hint:
col1 = []
col2 = []
for i in range(4):
for j in range(4):
for k in range(4):
col1.append([i + 1, j + 1, k + 1])
for l in range(3):
col2.append([i + 1, (j + l + 1) % 4 + 1, k + 1])
print ("The list\n" + str(col1) + "\nhas " + str(len(col1)) + " entries")
print ("The list\n" + str(col2) + "\nhas " + str(len(col2)) + " entries")
This yields:
The list
[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]
has 64 entries
The list
[[1, 2, 1], [1, 3, 1], [1, 4, 1], [1, 2, 2], [1, 3, 2], [1, 4, 2], [1, 2, 3], [1, 3, 3], [1, 4, 3], [1, 2, 4], [1, 3, 4], [1, 4, 4], [1, 3, 1], [1, 4, 1], [1, 1, 1], [1, 3, 2], [1, 4, 2], [1, 1, 2], [1, 3, 3], [1, 4, 3], [1, 1, 3], [1, 3, 4], [1, 4, 4], [1, 1, 4], [1, 4, 1], [1, 1, 1], [1, 2, 1], [1, 4, 2], [1, 1, 2], [1, 2, 2], [1, 4, 3], [1, 1, 3], [1, 2, 3], [1, 4, 4], [1, 1, 4], [1, 2, 4], [1, 1, 1], [1, 2, 1], [1, 3, 1], [1, 1, 2], [1, 2, 2], [1, 3, 2], [1, 1, 3], [1, 2, 3], [1, 3, 3], [1, 1, 4], [1, 2, 4], [1, 3, 4], [2, 2, 1], [2, 3, 1], [2, 4, 1], [2, 2, 2], [2, 3, 2], [2, 4, 2], [2, 2, 3], [2, 3, 3], [2, 4, 3], [2, 2, 4], [2, 3, 4], [2, 4, 4], [2, 3, 1], [2, 4, 1], [2, 1, 1], [2, 3, 2], [2, 4, 2], [2, 1, 2], [2, 3, 3], [2, 4, 3], [2, 1, 3], [2, 3, 4], [2, 4, 4], [2, 1, 4], [2, 4, 1], [2, 1, 1], [2, 2, 1], [2, 4, 2], [2, 1, 2], [2, 2, 2], [2, 4, 3], [2, 1, 3], [2, 2, 3], [2, 4, 4], [2, 1, 4], [2, 2, 4], [2, 1, 1], [2, 2, 1], [2, 3, 1], [2, 1, 2], [2, 2, 2], [2, 3, 2], [2, 1, 3], [2, 2, 3], [2, 3, 3], [2, 1, 4], [2, 2, 4], [2, 3, 4], [3, 2, 1], [3, 3, 1], [3, 4, 1], [3, 2, 2], [3, 3, 2], [3, 4, 2], [3, 2, 3], [3, 3, 3], [3, 4, 3], [3, 2, 4], [3, 3, 4], [3, 4, 4], [3, 3, 1], [3, 4, 1], [3, 1, 1], [3, 3, 2], [3, 4, 2], [3, 1, 2], [3, 3, 3], [3, 4, 3], [3, 1, 3], [3, 3, 4], [3, 4, 4], [3, 1, 4], [3, 4, 1], [3, 1, 1], [3, 2, 1], [3, 4, 2], [3, 1, 2], [3, 2, 2], [3, 4, 3], [3, 1, 3], [3, 2, 3], [3, 4, 4], [3, 1, 4], [3, 2, 4], [3, 1, 1], [3, 2, 1], [3, 3, 1], [3, 1, 2], [3, 2, 2], [3, 3, 2], [3, 1, 3], [3, 2, 3], [3, 3, 3], [3, 1, 4], [3, 2, 4], [3, 3, 4], [4, 2, 1], [4, 3, 1], [4, 4, 1], [4, 2, 2], [4, 3, 2], [4, 4, 2], [4, 2, 3], [4, 3, 3], [4, 4, 3], [4, 2, 4], [4, 3, 4], [4, 4, 4], [4, 3, 1], [4, 4, 1], [4, 1, 1], [4, 3, 2], [4, 4, 2], [4, 1, 2], [4, 3, 3], [4, 4, 3], [4, 1, 3], [4, 3, 4], [4, 4, 4], [4, 1, 4], [4, 4, 1], [4, 1, 1], [4, 2, 1], [4, 4, 2], [4, 1, 2], [4, 2, 2], [4, 4, 3], [4, 1, 3], [4, 2, 3], [4, 4, 4], [4, 1, 4], [4, 2, 4], [4, 1, 1], [4, 2, 1], [4, 3, 1], [4, 1, 2], [4, 2, 2], [4, 3, 2], [4, 1, 3], [4, 2, 3], [4, 3, 3], [4, 1, 4], [4, 2, 4], [4, 3, 4]]
has 192 entries
itertools.combinations_with_replacement will sort the results and remove duplicates. (1,2,1) will be sorted to (1,1,2) and removed because (1,1,2) already exists. What you are looking for is itertools.product.
lst = [1,2,3,4]
ref = list(it.product(lst, repeat=3))
>>> len(ref)
64
Related
OpenAI Gym: Walk through all possible actions in an action space
I want to build a brute-force approach that tests all actions in a Gym action space before selecting the best one. Is there any simple, straight-forward way to get all possible actions? Specifically, my action space is import gym action_space = gym.spaces.MultiDiscrete([5 for _ in range(4)]) I know I can sample a random action with action_space.sample() and also check if an action is contained in the action space, but I want to generate a list of all possible action within that space. Is there anything more elegant (and performant) than just a bunch of for loops? The problem with for loops is that I want it to work with any size of action space, so I cannot hard-code 4 for loops to walk through the different actions.
The actions in a gym environment are usually represented by integers only, this mean if you get the total number of possible actions, then an array of all possible actions can be created. The way to get the total number of possible actions in a gym environment depends on the type of action space it has, for your case it's a MultiDiscrete action space and thus the attribute nvec can be used as mentioned here by #Valentin Macé like so -: >> print(env.action_space.nvec) array([5, 5, 5, 5], dtype=int64) Note that the attribute nvec stands for n vector, since its output is a multidimensional vector. Also note that the attribute is a numpy array. Now that we have the array to convert it into a list of lists of actions assuming that since the action_space.sample function returns a numpy array of a random function from each of the dimensions of the MultiDiscrete action_space i.e. -: >> env.action_space.sample() # This does not return a single action but 4 actions for your case since you have a multi discrete action space of length 4. array([2, 2, 0, 1], dtype=int64) So thus to convert the array to a list of lists of possible actions in each dimensions we can use list comprehensions like so -: >> [list(range(1, (k + 1))) for k in action_space.nvec] [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]] Note that this is scalable to any number of dimensions and is also quite efficient performance wise. Now you can loop over the possible actions in each dimension using only two loops like so -: possible_actions = [list(range(1, (k + 1))) for k in action_space.nvec] for action_dim in possible_actions : for action in action_dim : # Find best action..... pass For more info about the same I would like you to also visit this thread on github, with a somewhat similar issue being discussed incase you find the same useful. EDIT: So as per the comment of yours #CGFoX I assume that you want it such that all the possible combination vectors of the actions can be generated as a list for any number of dimensions, somewhat like so -: >> get_actions() [[1, 1, 1, 1], [1, 1, 1, 2] ....] # For all possible combinations. The same can be achieved like so using recursion and with only two loops, this is also expandable to as many dimensions as provided. def flatten(actions) : # This function flattens any actions passed somewhat like so -: # INPUT -: [[1, 2, 3], 4, 5] # OUTPUT -: [1, 2, 3, 4, 5] new_actions = [] # Initializing the new flattened list of actions. for action in actions : # Loop through the actions if type(action) == list : # If any actions is a pair of actions i.e. a list e.g. [1, 1] then # add it's elements to the new_actions list. new_actions += action elif type(action) == int : # If the action is an integer then append it directly to the new_actions # list. new_actions.append(action) # Returns the new_actions list generated. return new_actions def get_actions(possible_actions) : # This functions recieves as input the possibilities of actions for every dimension # and returns all possible dimensional combinations for the same. # Like so -: # INPUT-: [[1, 2, 3, 4], [1, 2, 3, 4]] # Example for 2 dimensions but can be scaled for any. # OUTPUT-: [[1, 1], [1, 2], [1, 3] ... [4, 1] ... [4, 4]] if len(possible_actions) == 1 : # If there is only one possible list of actions then it itself is the # list containing all possible combinations and thus is returned. return possible_actions pairs = [] # Initializing a list to contain all pairs of actions generated. for action in possible_actions[0] : # Now we loop over the first set of possibilities of actions i.e. index 0 # and we make pairs of it with the second set i.e. index 1, appending each pair # to the pairs list. # NOTE: Incase the function is recursively called the first set of possibilities # of actions may contain vectors and thus the newly formed pair has to be flattened. # i.e. If a pair has already been made in previous generation like so -: # [[[1, 1], [2, 2], [3, 3] ... ], [1, 2, 3, 4]] # Then the pair formed will be this -: [[[1, 1], 1], [[1, 1], 2] ... ] # But we want them to be flattened like so -: [[1, 1, 1], [1, 1, 2] ... ] for action2 in possible_actions[1] : pairs.append(flatten([action, action2])) # Now we create a new list of all possible set of actions by combining the # newly generated pairs and the sets of possibilities of actions that have not # been paired i.e. sets other than the first and the second. # NOTE: When we made pairs we did so only for the first two indexes and not for # all thus to do so we make a new list with the sets that remained unpaired # and the paired set. i.e. # BEFORE PAIRING -: [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] # AFTER PAIRING -: [[[1, 1], [1, 2] ... ], [1, 2, 3, 4]] # Notice how the third set # i.e. the index 2 is still unpaired and first two sets have been paired. new_possible_actions = [pairs] + possible_actions[2 : ] # Now we recurse the function and call it within itself to make pairs for the # left out sets, Note that since the first two sets were combined to form a paired # first set now this set will be paired with the third set. # This recursion will keep happening until all the sets have been paired to form # a single set with all possible combinations. possible_action_vectors = get_actions(new_possible_actions) # Finally the result of the recursion is returned. # NOTE: Only the first index is returned since now the first index contains the # paired set of actions. return possible_action_vectors[0] Once we have this function defined it can be used with our previously generated set of possibilities of actions to get all possible combinations like so -: possible_actions = [list(range(1, (k + 1))) for k in action_space.nvec] print(get_actions(possible_actions)) >> [[1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 1, 3], [1, 1, 1, 4], [1, 1, 1, 5], `[1, 1, 2, 1], [1, 1, 2, 2], [1, 1, 2, 3], [1, 1, 2, 4], [1, 1, 2, 5], [1, 1, 3, 1], [1, 1, 3, 2], [1, 1, 3, 3], [1, 1, 3, 4], [1, 1, 3, 5], [1, 1, 4, 1], [1, 1, 4, 2], [1, 1, 4, 3], [1, 1, 4, 4], [1, 1, 4, 5], [1, 1, 5, 1], [1, 1, 5, 2], [1, 1, 5, 3], [1, 1, 5, 4], [1, 1, 5, 5], [1, 2, 1, 1], [1, 2, 1, 2], [1, 2, 1, 3], [1, 2, 1, 4], [1, 2, 1, 5], [1, 2, 2, 1], [1, 2, 2, 2], [1, 2, 2, 3], [1, 2, 2, 4], [1, 2, 2, 5], [1, 2, 3, 1], [1, 2, 3, 2], [1, 2, 3, 3], [1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 1], [1, 2, 4, 2], [1, 2, 4, 3], [1, 2, 4, 4], [1, 2, 4, 5], [1, 2, 5, 1], [1, 2, 5, 2], [1, 2, 5, 3], [1, 2, 5, 4], [1, 2, 5, 5], [1, 3, 1, 1], [1, 3, 1, 2], [1, 3, 1, 3], [1, 3, 1, 4], [1, 3, 1, 5], [1, 3, 2, 1], [1, 3, 2, 2], [1, 3, 2, 3], [1, 3, 2, 4], [1, 3, 2, 5], [1, 3, 3, 1], [1, 3, 3, 2], [1, 3, 3, 3], [1, 3, 3, 4], [1, 3, 3, 5], [1, 3, 4, 1], [1, 3, 4, 2], [1, 3, 4, 3], [1, 3, 4, 4], [1, 3, 4, 5], [1, 3, 5, 1], [1, 3, 5, 2], [1, 3, 5, 3], [1, 3, 5, 4], [1, 3, 5, 5], [1, 4, 1, 1], [1, 4, 1, 2], [1, 4, 1, 3], [1, 4, 1, 4], [1, 4, 1, 5], [1, 4, 2, 1], [1, 4, 2, 2], [1, 4, 2, 3], [1, 4, 2, 4], [1, 4, 2, 5], [1, 4, 3, 1], [1, 4, 3, 2], [1, 4, 3, 3], [1, 4, 3, 4], [1, 4, 3, 5], [1, 4, 4, 1], [1, 4, 4, 2], [1, 4, 4, 3], [1, 4, 4, 4], [1, 4, 4, 5], [1, 4, 5, 1], [1, 4, 5, 2], [1, 4, 5, 3], [1, 4, 5, 4], [1, 4, 5, 5], [1, 5, 1, 1], [1, 5, 1, 2], [1, 5, 1, 3], [1, 5, 1, 4], [1, 5, 1, 5], [1, 5, 2, 1], [1, 5, 2, 2], [1, 5, 2, 3], [1, 5, 2, 4], [1, 5, 2, 5], [1, 5, 3, 1], [1, 5, 3, 2], [1, 5, 3, 3], [1, 5, 3, 4], [1, 5, 3, 5], [1, 5, 4, 1], [1, 5, 4, 2], [1, 5, 4, 3], [1, 5, 4, 4], [1, 5, 4, 5], [1, 5, 5, 1], [1, 5, 5, 2], [1, 5, 5, 3], [1, 5, 5, 4], [1, 5, 5, 5], [2, 1, 1, 1], [2, 1, 1, 2], [2, 1, 1, 3], [2, 1, 1, 4], [2, 1, 1, 5], [2, 1, 2, 1], [2, 1, 2, 2], [2, 1, 2, 3], [2, 1, 2, 4], [2, 1, 2, 5], [2, 1, 3, 1], [2, 1, 3, 2], [2, 1, 3, 3], [2, 1, 3, 4], [2, 1, 3, 5], [2, 1, 4, 1], [2, 1, 4, 2], [2, 1, 4, 3], [2, 1, 4, 4], [2, 1, 4, 5], [2, 1, 5, 1], [2, 1, 5, 2], [2, 1, 5, 3], [2, 1, 5, 4], [2, 1, 5, 5], [2, 2, 1, 1], [2, 2, 1, 2], [2, 2, 1, 3], [2, 2, 1, 4], [2, 2, 1, 5], [2, 2, 2, 1], [2, 2, 2, 2], [2, 2, 2, 3], [2, 2, 2, 4], [2, 2, 2, 5], [2, 2, 3, 1], [2, 2, 3, 2], [2, 2, 3, 3], [2, 2, 3, 4], [2, 2, 3, 5], [2, 2, 4, 1], [2, 2, 4, 2], [2, 2, 4, 3], [2, 2, 4, 4], [2, 2, 4, 5], [2, 2, 5, 1], [2, 2, 5, 2], [2, 2, 5, 3], [2, 2, 5, 4], [2, 2, 5, 5], [2, 3, 1, 1], [2, 3, 1, 2], [2, 3, 1, 3], [2, 3, 1, 4], [2, 3, 1, 5], [2, 3, 2, 1], [2, 3, 2, 2], [2, 3, 2, 3], [2, 3, 2, 4], [2, 3, 2, 5], [2, 3, 3, 1], [2, 3, 3, 2], [2, 3, 3, 3], [2, 3, 3, 4], [2, 3, 3, 5], [2, 3, 4, 1], [2, 3, 4, 2], [2, 3, 4, 3], [2, 3, 4, 4], [2, 3, 4, 5], [2, 3, 5, 1], [2, 3, 5, 2], [2, 3, 5, 3], [2, 3, 5, 4], [2, 3, 5, 5], [2, 4, 1, 1], [2, 4, 1, 2], [2, 4, 1, 3], [2, 4, 1, 4], [2, 4, 1, 5], [2, 4, 2, 1], [2, 4, 2, 2], [2, 4, 2, 3], [2, 4, 2, 4], [2, 4, 2, 5], [2, 4, 3, 1], [2, 4, 3, 2], [2, 4, 3, 3], [2, 4, 3, 4], [2, 4, 3, 5], [2, 4, 4, 1], [2, 4, 4, 2], [2, 4, 4, 3], [2, 4, 4, 4], [2, 4, 4, 5], [2, 4, 5, 1], [2, 4, 5, 2], [2, 4, 5, 3], [2, 4, 5, 4], [2, 4, 5, 5], [2, 5, 1, 1], [2, 5, 1, 2], [2, 5, 1, 3], [2, 5, 1, 4], [2, 5, 1, 5], [2, 5, 2, 1], [2, 5, 2, 2], [2, 5, 2, 3], [2, 5, 2, 4], [2, 5, 2, 5], [2, 5, 3, 1], [2, 5, 3, 2], [2, 5, 3, 3], [2, 5, 3, 4], [2, 5, 3, 5], [2, 5, 4, 1], [2, 5, 4, 2], [2, 5, 4, 3], [2, 5, 4, 4], [2, 5, 4, 5], [2, 5, 5, 1], [2, 5, 5, 2], [2, 5, 5, 3], [2, 5, 5, 4], [2, 5, 5, 5], [3, 1, 1, 1], [3, 1, 1, 2], [3, 1, 1, 3], [3, 1, 1, 4], [3, 1, 1, 5], [3, 1, 2, 1], [3, 1, 2, 2], [3, 1, 2, 3], [3, 1, 2, 4], [3, 1, 2, 5], [3, 1, 3, 1], [3, 1, 3, 2], [3, 1, 3, 3], [3, 1, 3, 4], [3, 1, 3, 5], [3, 1, 4, 1], [3, 1, 4, 2], [3, 1, 4, 3], [3, 1, 4, 4], [3, 1, 4, 5], [3, 1, 5, 1], [3, 1, 5, 2], [3, 1, 5, 3], [3, 1, 5, 4], [3, 1, 5, 5], [3, 2, 1, 1], [3, 2, 1, 2], [3, 2, 1, 3], [3, 2, 1, 4], [3, 2, 1, 5], [3, 2, 2, 1], [3, 2, 2, 2], [3, 2, 2, 3], [3, 2, 2, 4], [3, 2, 2, 5], [3, 2, 3, 1], [3, 2, 3, 2], [3, 2, 3, 3], [3, 2, 3, 4], [3, 2, 3, 5], [3, 2, 4, 1], [3, 2, 4, 2], [3, 2, 4, 3], [3, 2, 4, 4], [3, 2, 4, 5], [3, 2, 5, 1], [3, 2, 5, 2], [3, 2, 5, 3], [3, 2, 5, 4], [3, 2, 5, 5], [3, 3, 1, 1], [3, 3, 1, 2], [3, 3, 1, 3], [3, 3, 1, 4], [3, 3, 1, 5], [3, 3, 2, 1], [3, 3, 2, 2], [3, 3, 2, 3], [3, 3, 2, 4], [3, 3, 2, 5], [3, 3, 3, 1], [3, 3, 3, 2], [3, 3, 3, 3], [3, 3, 3, 4], [3, 3, 3, 5], [3, 3, 4, 1], [3, 3, 4, 2], [3, 3, 4, 3], [3, 3, 4, 4], [3, 3, 4, 5], [3, 3, 5, 1], [3, 3, 5, 2], [3, 3, 5, 3], [3, 3, 5, 4], [3, 3, 5, 5], [3, 4, 1, 1], [3, 4, 1, 2], [3, 4, 1, 3], [3, 4, 1, 4], [3, 4, 1, 5], [3, 4, 2, 1], [3, 4, 2, 2], [3, 4, 2, 3], [3, 4, 2, 4], [3, 4, 2, 5], [3, 4, 3, 1], [3, 4, 3, 2], [3, 4, 3, 3], [3, 4, 3, 4], [3, 4, 3, 5], [3, 4, 4, 1], [3, 4, 4, 2], [3, 4, 4, 3], [3, 4, 4, 4], [3, 4, 4, 5], [3, 4, 5, 1], [3, 4, 5, 2], [3, 4, 5, 3], [3, 4, 5, 4], [3, 4, 5, 5], [3, 5, 1, 1], [3, 5, 1, 2], [3, 5, 1, 3], [3, 5, 1, 4], [3, 5, 1, 5], [3, 5, 2, 1], [3, 5, 2, 2], [3, 5, 2, 3], [3, 5, 2, 4], [3, 5, 2, 5], [3, 5, 3, 1], [3, 5, 3, 2], [3, 5, 3, 3], [3, 5, 3, 4], [3, 5, 3, 5], [3, 5, 4, 1], [3, 5, 4, 2], [3, 5, 4, 3], [3, 5, 4, 4], [3, 5, 4, 5], [3, 5, 5, 1], [3, 5, 5, 2], [3, 5, 5, 3], [3, 5, 5, 4], [3, 5, 5, 5], [4, 1, 1, 1], [4, 1, 1, 2], [4, 1, 1, 3], [4, 1, 1, 4], [4, 1, 1, 5], [4, 1, 2, 1], [4, 1, 2, 2], [4, 1, 2, 3], [4, 1, 2, 4], [4, 1, 2, 5], [4, 1, 3, 1], [4, 1, 3, 2], [4, 1, 3, 3], [4, 1, 3, 4], [4, 1, 3, 5], [4, 1, 4, 1], [4, 1, 4, 2], [4, 1, 4, 3], [4, 1, 4, 4], [4, 1, 4, 5], [4, 1, 5, 1], [4, 1, 5, 2], [4, 1, 5, 3], [4, 1, 5, 4], [4, 1, 5, 5], [4, 2, 1, 1], [4, 2, 1, 2], [4, 2, 1, 3], [4, 2, 1, 4], [4, 2, 1, 5], [4, 2, 2, 1], [4, 2, 2, 2], [4, 2, 2, 3], [4, 2, 2, 4], [4, 2, 2, 5], [4, 2, 3, 1], [4, 2, 3, 2], [4, 2, 3, 3], [4, 2, 3, 4], [4, 2, 3, 5], [4, 2, 4, 1], [4, 2, 4, 2], [4, 2, 4, 3], [4, 2, 4, 4], [4, 2, 4, 5], [4, 2, 5, 1], [4, 2, 5, 2], [4, 2, 5, 3], [4, 2, 5, 4], [4, 2, 5, 5], [4, 3, 1, 1], [4, 3, 1, 2], [4, 3, 1, 3], [4, 3, 1, 4], [4, 3, 1, 5], [4, 3, 2, 1], [4, 3, 2, 2], [4, 3, 2, 3], [4, 3, 2, 4], [4, 3, 2, 5], [4, 3, 3, 1], [4, 3, 3, 2], [4, 3, 3, 3], [4, 3, 3, 4], [4, 3, 3, 5], [4, 3, 4, 1], [4, 3, 4, 2], [4, 3, 4, 3], [4, 3, 4, 4], [4, 3, 4, 5], [4, 3, 5, 1], [4, 3, 5, 2], [4, 3, 5, 3], [4, 3, 5, 4], [4, 3, 5, 5], [4, 4, 1, 1], [4, 4, 1, 2], [4, 4, 1, 3], [4, 4, 1, 4], [4, 4, 1, 5], [4, 4, 2, 1], [4, 4, 2, 2], [4, 4, 2, 3], [4, 4, 2, 4], [4, 4, 2, 5], [4, 4, 3, 1], [4, 4, 3, 2], [4, 4, 3, 3], [4, 4, 3, 4], [4, 4, 3, 5], [4, 4, 4, 1], [4, 4, 4, 2], [4, 4, 4, 3], [4, 4, 4, 4], [4, 4, 4, 5], [4, 4, 5, 1], [4, 4, 5, 2], [4, 4, 5, 3], [4, 4, 5, 4], [4, 4, 5, 5], [4, 5, 1, 1], [4, 5, 1, 2], [4, 5, 1, 3], [4, 5, 1, 4], [4, 5, 1, 5], [4, 5, 2, 1], [4, 5, 2, 2], [4, 5, 2, 3], [4, 5, 2, 4], [4, 5, 2, 5], [4, 5, 3, 1], [4, 5, 3, 2], [4, 5, 3, 3], [4, 5, 3, 4], [4, 5, 3, 5], [4, 5, 4, 1], [4, 5, 4, 2], [4, 5, 4, 3], [4, 5, 4, 4], [4, 5, 4, 5], [4, 5, 5, 1], [4, 5, 5, 2], [4, 5, 5, 3], [4, 5, 5, 4], [4, 5, 5, 5], [5, 1, 1, 1], [5, 1, 1, 2], [5, 1, 1, 3], [5, 1, 1, 4], [5, 1, 1, 5], [5, 1, 2, 1], [5, 1, 2, 2], [5, 1, 2, 3], [5, 1, 2, 4], [5, 1, 2, 5], [5, 1, 3, 1], [5, 1, 3, 2], [5, 1, 3, 3], [5, 1, 3, 4], [5, 1, 3, 5], [5, 1, 4, 1], [5, 1, 4, 2], [5, 1, 4, 3], [5, 1, 4, 4], [5, 1, 4, 5], [5, 1, 5, 1], [5, 1, 5, 2], [5, 1, 5, 3], [5, 1, 5, 4], [5, 1, 5, 5], [5, 2, 1, 1], [5, 2, 1, 2], [5, 2, 1, 3], [5, 2, 1, 4], [5, 2, 1, 5], [5, 2, 2, 1], [5, 2, 2, 2], [5, 2, 2, 3], [5, 2, 2, 4], [5, 2, 2, 5], [5, 2, 3, 1], [5, 2, 3, 2], [5, 2, 3, 3], [5, 2, 3, 4], [5, 2, 3, 5], [5, 2, 4, 1], [5, 2, 4, 2], [5, 2, 4, 3], [5, 2, 4, 4], [5, 2, 4, 5], [5, 2, 5, 1], [5, 2, 5, 2], [5, 2, 5, 3], [5, 2, 5, 4], [5, 2, 5, 5], [5, 3, 1, 1], [5, 3, 1, 2], [5, 3, 1, 3], [5, 3, 1, 4], [5, 3, 1, 5], [5, 3, 2, 1], [5, 3, 2, 2], [5, 3, 2, 3], [5, 3, 2, 4], [5, 3, 2, 5], [5, 3, 3, 1], [5, 3, 3, 2], [5, 3, 3, 3], [5, 3, 3, 4], [5, 3, 3, 5], [5, 3, 4, 1], [5, 3, 4, 2], [5, 3, 4, 3], [5, 3, 4, 4], [5, 3, 4, 5], [5, 3, 5, 1], [5, 3, 5, 2], [5, 3, 5, 3], [5, 3, 5, 4], [5, 3, 5, 5], [5, 4, 1, 1], [5, 4, 1, 2], [5, 4, 1, 3], [5, 4, 1, 4], [5, 4, 1, 5], [5, 4, 2, 1], [5, 4, 2, 2], [5, 4, 2, 3], [5, 4, 2, 4], [5, 4, 2, 5], [5, 4, 3, 1], [5, 4, 3, 2], [5, 4, 3, 3], [5, 4, 3, 4], [5, 4, 3, 5], [5, 4, 4, 1], [5, 4, 4, 2], [5, 4, 4, 3], [5, 4, 4, 4], [5, 4, 4, 5], [5, 4, 5, 1], [5, 4, 5, 2], [5, 4, 5, 3], [5, 4, 5, 4], [5, 4, 5, 5], [5, 5, 1, 1], [5, 5, 1, 2], [5, 5, 1, 3], [5, 5, 1, 4], [5, 5, 1, 5], [5, 5, 2, 1], [5, 5, 2, 2], [5, 5, 2, 3], [5, 5, 2, 4], [5, 5, 2, 5], [5, 5, 3, 1], [5, 5, 3, 2], [5, 5, 3, 3], [5, 5, 3, 4], [5, 5, 3, 5], [5, 5, 4, 1], [5, 5, 4, 2], [5, 5, 4, 3], [5, 5, 4, 4], [5, 5, 4, 5], [5, 5, 5, 1], [5, 5, 5, 2], [5, 5, 5, 3], [5, 5, 5, 4], [5, 5, 5, 5]] EDIT-2 : I have fixed some code which previously was returning a nested list, now the list returned is the one with the pairs and is not nested within another list. EDIT-3-: Fixed my spelling mistakes.
One could also use the function below, to make an explicit list of all states or actions in the observation or action space respectively. def get_space_list(space): """ Converts gym `space`, constructed from `types`, to list `space_list` """ # -------------------------------- # types = [ gym.spaces.multi_binary.MultiBinary, gym.spaces.discrete.Discrete, gym.spaces.multi_discrete.MultiDiscrete, gym.spaces.dict.Dict, gym.spaces.tuple.Tuple, ] if type(space) not in types: raise ValueError(f'input space {space} is not constructed from spaces of types:' + '\n' + str(types)) # -------------------------------- # if type(space) is gym.spaces.multi_binary.MultiBinary: return [ np.reshape(np.array(element), space.n) for element in itertools.product( *[range(2)] * np.prod(space.n) ) ] if type(space) is gym.spaces.discrete.Discrete: return list(range(space.n)) if type(space) is gym.spaces.multi_discrete.MultiDiscrete: return [ np.array(element) for element in itertools.product( *[range(n) for n in space.nvec] ) ] if type(space) is gym.spaces.dict.Dict: keys = space.spaces.keys() values_list = itertools.product( *[get_space_list(sub_space) for sub_space in space.spaces.values()] ) return [ {key: value for key, value in zip(keys, values)} for values in values_list ] return space_list if type(space) is gym.spaces.tuple.Tuple: return [ list(element) for element in itertools.product( *[get_space_list(sub_space) for sub_space in space.spaces] ) ] # -------------------------------- #
List with non-repeating sublists from given list
How to create a list with n-size non-repeating sublists from given list? I think the example will explain a lot. given_list = [1, 2, 3, 4, 5] n = 3 desired_list = [[1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5], [3,4,5]] EDIT: I forgot to add some important combinations
Not sure if you want combinations or permutations, so here are both: Permutations You can use permutations from itertools to find all permutations of a given list: from itertools import permutations given_list = [1, 2, 3, 4, 5] n = 3 print([list(i) for i in permutations(given_list, n)]) Output: [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 2], [1, 3, 4], [1, 3, 5], [1, 4, 2], [1 , 4, 3], [1, 4, 5], [1, 5, 2], [1, 5, 3], [1, 5, 4], [2, 1, 3], [2, 1, 4], [2, 1 , 5], [2, 3, 1], [2, 3, 4], [2, 3, 5], [2, 4, 1], [2, 4, 3], [2, 4, 5], [2, 5, 1 ], [2, 5, 3], [2, 5, 4], [3, 1, 2], [3, 1, 4], [3, 1, 5], [3, 2, 1], [3, 2, 4], [3, 2, 5], [3, 4, 1], [3, 4, 2], [3, 4, 5], [3, 5, 1], [3, 5, 2], [3, 5, 4], [4, 1, 2], [4, 1, 3], [4, 1, 5], [4, 2, 1], [4, 2, 3], [4, 2, 5], [4, 3, 1], [4, 3, 2], [4, 3, 5], [4, 5, 1], [4, 5, 2], [4, 5, 3], [5, 1, 2], [5, 1, 3], [5, 1, 4] , [5, 2, 1], [5, 2, 3], [5, 2, 4], [5, 3, 1], [5, 3, 2], [5, 3, 4], [5, 4, 1], [ 5, 4, 2], [5, 4, 3]] Combinations And you can use combinations from itertools to find all the combinations of a given list: from itertools import combinations given_list = [1, 2, 3, 4, 5] n = 3 print([list(i) for i in combinations(given_list, n)]) Output: [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2 , 3, 5], [2, 4, 5], [3, 4, 5]]
A fast implementation of permutations: sub perm { my ($init,$k) = #_; my $n=length($init); my $dn=$n; my $out=""; my $m=$k; for (my $i=0;$i<$n;$i++) { my $ind=$m % $dn; $out.=substr($init,$ind,1); $m=$m / $dn; $dn--; substr($init,$ind,1,substr($init,$dn,1)); } return $out } k = 0 .. length(init)-1; each k giving an unique permutation, seemly randomly. to calculate the factorial length(init)! sub fac { my ($f) = #_; my $fac=1; while ($f>1) { $fac*=$f; $f-- } return $fac }
How to generate all possible k size vectors in a matrix (diagonals included)?
Given this matrix: x = [[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]] What is an efficient way to return all the possible 4 by 1 vectors and 1 by 4 matrix in this matrix. As well as any 4 diagonal spaces joined in a line. For example: [1,1,1,1] would appear 3 times Diagonals also need to be addressed so [1,2,3,4] would be included as a row but also a diagonal.
Splitting the problem into two steps: Step 1 - get all horizontal, vertical and diagonal lines Diagonals are tackled using the fact either i+j, or respectively i-j, is constant for the indexes i, j x = [[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]] pprint.pprint(x) # [[1, 2, 3, 4, 5], # [1, 2, 3, 4, 5], # [1, 2, 3, 4, 5], # [1, 2, 3, 4, 5], # [1, 2, 3, 4, 5], # [1, 2, 3, 4, 5]] all_lines = ( # Horizontal [x[i] for i in range(len(x))] + # Vertical [[x[i][j] for i in range(len(x))] for j in range(len(x[0]))] + # Diagonal k = i - j [[x[k+j][j] for j in range(len(x[0])) if 0 <= k+j < len(x)] for k in range(-len(x[0])+1, len(x))] + # Diagonal k = i + j [[x[k-j][j] for j in range(len(x[0])) if 0 <= k-j < len(x)] for k in range(len(x[0])+len(x)-1)] ) >>> pprint.pprint(all_lines) [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [5], [4, 5], [3, 4, 5], [2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3], [1, 2], [1], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5]] Step 2 - for each line select each 4-length slice ans = [a[i:i+4] for i in range(len(a)-4+1) for a in all_lines if len(a[i:i+4]) == 4] >>> ans = [a[i:i+4] for i in range(len(a)-4+1) for a in all_lines if len(a[i:i+4]) == 4] >>> pprint.pprint(ans) [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5], [2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5]] Maybe not be the most efficient but it's at least a way of doing it. There will likely be a way of using itertools combinations to simplify this dramatically.
[Python]: generate and array of all possible combinations
I have a very straightforward combination problem. I have two arrays (a and b). Array a indicates all the values one of the three slots in array b can take on. Each slot in array b can have a value between 1 and 5. An example of which would be [1, 4, 5]. I would like to generate an array (c) with all possible combinations. I like to extend the basic example larger arrays. Input: a = [1, 2, 3, 4, 5] b = [1, 2, 3] Output: c = [[1, 1, 1], [1, 1, 2],[1, 1, 3], [1, 1, 4], [1, 1, 5], [1, 2, 1], [1, 2, 2],[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 1], [1, 3, 2],[1, 3, 3], [1, 3, 4], [1, 3, 5], [1, 4, 1], [1, 4, 2],[1, 4, 3], [1, 4, 4], [1, 4, 5], [1, 5, 1], [1, 5, 2],[1, 5, 3], [1, 5, 4], [1, 5, 5], [2, 1, 1], [2, 1, 2],[2, 1, 3], [2, 1, 4], [2, 1, 5], [2, 2, 1], [2, 2, 2],[2, 2, 3], [2, 2, 4], [2, 2, 5], [2, 3, 1], [2, 3, 2],[2, 3, 3], [2, 3, 4], [2, 3, 5], [2, 4, 1], [2, 4, 2],[2, 4, 3], [2, 4, 4], [2, 4, 5], [2, 5, 1], [2, 5, 2],[2, 5, 3], [2, 5, 4], [2, 5, 5], [3, 1, 1], [3, 1, 2],[3, 1, 3], [3, 1, 4], [3, 1, 5], [3, 2, 1], [3, 2, 2],[3, 2, 3], [3, 2, 4], [3, 2, 5], [3, 3, 1], [3, 3, 2],[3, 3, 3], [3, 3, 4], [3, 3, 5], [3, 4, 1], [3, 4, 2],[3, 4, 3], [3, 4, 4], [3, 4, 5], [3, 5, 1], [3, 5, 2],[3, 5, 3], [3, 5, 4], [3, 5, 5], [4, 1, 1], [4, 1, 2],[4, 1, 3], [4, 1, 4], [4, 1, 5], [4, 2, 1], [4, 2, 2],[4, 2, 3], [4, 2, 4], [4, 2, 5], [4, 3, 1], [4, 3, 2],[4, 3, 3], [4, 3, 4], [4, 3, 5], [4, 4, 1], [4, 4, 2],[4, 4, 3], [4, 4, 4], [4, 4, 5], [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5], [5, 1, 1], [5, 1, 2],[5, 1, 3], [5, 1, 4], [5, 1, 5], [5, 2, 1], [5, 2, 2],[5, 2, 3], [5, 2, 4], [5, 2, 5], [5, 3, 1], [5, 3, 2],[5, 3, 3], [5, 3, 4], [5, 3, 5], [5, 4, 1], [5, 4, 2],[5, 4, 3], [5, 4, 4], [5, 4, 5], [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5]] Solution for the problem above: d = [] for i in range(len(a)): for j in range(len(a)): for k in range(len(a)): e = [] e.append(i+1) e.append(j+1) e.append(k+1) d.append(e) I am looking for a more generic way. One which can accommodate larger arrays (see below) without the need to use a nested for loop structure. I searched for a comparable example, but was unable to find one on stackoverflow. Input: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
You are looking for itertools.product(). a = [1, 2, 3, 4, 5] b = 3 # Actually, you just need the length of the array, values do not matter c = itertools.product(a, repeat=b) Note that this returns an iterator, you may need to cast it using list() but be aware this can take forever and highly consume memory if the sizes grow.
In the general case, you should of course use the itertools module, in this particular case itertools.product, as explained in the other answer. If you want to implement the function yourself, you can use recursion to make it applicable to any array sizes. Also, you should probably make it a generator function (using yield instead of return), as the result could be rather long. You can try something like this: def combinations(lst, num): if num > 0: for x in lst: for comb in combinations(lst, num - 1): yield [x] + comb else: yield []
List recursion?
I wrote a function: def expandList(aList): """expand a list""" finalList = [] for j in aList: tempList = [] if type(j) != type(list): tempList.append(j) finalList.extend(tempList) else: finalList.extend(expandList(j)) return finalList to expand nested list within themselves like: [[1, [2, 3], [3, 2]], [2, [1, 3], [3, 1]], [3, [1, 2], [2, 1]]] into: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]] or [[1, [2, [3, 4], [4, 3]], [3, [2, 4], [4, 2]], [4, [2, 3], [3, 2]]], [2, [1, [3, 4], [4, 3]], [3, [1, 4], [4, 1]], [4, [1, 3], [3, 1]]], [3, [1, [2, 4], [4, 2]], [2, [1, 4], [4, 1]], [4, [1, 2], [2, 1]]], [4, [1, [2, 3], [3, 2]], [2, [1, 3], [3, 1]], [3, [1, 2], [2, 1]]]] into: [[1, 2, 3, 4],[1, 2, 4, 3],[1, 3, 2, 4], [1, 3, 4, 2],[1, 4, 3, 2],[1, 4, 2, 3],[2, 1, 3, 4], [2, 1, 4, 3],[2, 3, 1, 4],[2, 3, 4, 1],[2, 4, 1, 3], [2, 4, 3, 1],[3, 1, 2, 4],[3, 1, 4, 2],[3, 2, 1, 4], [3, 2, 4, 1],[3, 4, 1, 2],[3, 4, 2, 1],[4, 1, 2, 3], [4, 1, 3, 2],[4, 2, 1, 3],[4, 2, 3, 1],[4, 3, 1, 2], [4, 3, 2, 1]] and so forth. I wish to be able to do this in any size of nested lists. My function doesn't seem to work right. What am I doing wrong? How can I fix/improve my function? Thank you in advance
First of all using following command is a wrong way for checking the list type : type(j) != type(list) because type(list) returns <type 'type'> actually you are getting the type of a type object that is a type. In edition you don't need to loop over your sub list and using extend method although you used it incorrect.Since your numbers are in the first index you can just convert it to list and append the rest to it. You can use a simple list comprehension : >>> [[[i[0]]+j for j in i[1:]] for i in l] [[[1, 2, 3], [1, 3, 2]], [[2, 1, 3], [2, 3, 1]], [[3, 1, 2], [3, 2, 1]]]