Sorry about the confusingly worded title, I'm fairly new to python development and I'm not sure how to approach the following problem.
I'm trying to solve an allocation style problem which I have boiled down to the following.
Take the following example of a nested list:
[[0, 3], [0, 1, 2], [3], [4], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
I need to find all ways to select one item from each sublist such that all integers 0 to 5 are selected.
In this case one way of doing so is:
Another way would be
I would also need this to be generalisable to longer lists with more numbers.
You could try something like below. ( Note that I have slightly modified the input list such that all the numbers from 0 through 5 is selected)
nested_list = [[0, 3], [0, 1, 2], [3], [4], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [3, 4, 5], [5, 9, 10]]
iter_obj = iter(nested_list)
for i, l in enumerate(iter_obj):
is_found = False
while not is_found:
if i in l:
print(f'selected {i} from list {l}')
is_found = True
else:
print(f'ignoring list {l} as it does not contain {i}')
l = next(iter_obj)
Result
selected 0 from list [0, 3]
selected 1 from list [0, 1, 2]
ignoring list [3] as it does not contain 2
ignoring list [4] as it does not contain 2
selected 2 from list [0, 1, 2, 3, 4, 5]
selected 3 from list [0, 1, 2, 3, 4, 5]
selected 4 from list [3, 4, 5]
selected 5 from list [5, 9, 10]
This script prints every combination that satisfies the criteria. The values in input list must be in range <0, lenght(input list)>
:
lst = [[0, 3], [0, 1, 2], [3], [4], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
def find_combination(lst, idxs=[]):
s = []
for i, idx in enumerate(idxs):
if 0 <= lst[i][idx] <= len(lst):
s.append(lst[i][idx])
if len(s) == len(lst) and len(set(s)) == len(lst):
yield s
for i, idx in enumerate(lst):
if len(idxs) == i:
for ii in range(len(lst[i])):
yield from find_combination(lst, idxs + [ii])
for c in find_combination(lst):
print(c)
Prints:
[0, 1, 3, 4, 2, 5]
[0, 1, 3, 4, 5, 2]
[0, 2, 3, 4, 1, 5]
[0, 2, 3, 4, 5, 1]
With the python builtin itertools module you can easily accomplish a different kind of combinatorics fast and memory efficient like:
product('ABCD', repeat=2) -> AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2) -> AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2) -> AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) -> AA AB AC AD BB BC BD CC CD DD
and even more, like "infinite iterators" and "iterators terminating on the shortest input sequence".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.