A difficult problem, given the list of lists (nested here no more than one level):
[['a', 'b'], 'c', ['d', 'e'], ['f', 'g'], 'h']
.. find all length lists, the same as the specified list, and contain all possible combinations of elements from the subscriptions, with exactly one element of this subscription in the same position as the original sublist (it should not even be put in words). That is, find this:
['a', 'c', 'd', 'f', 'h'] ['a', 'c', 'd', 'g', 'h'] ['a', 'c', 'e', 'f', 'h'] ['a', 'c', 'e', 'g', 'h'] ['b', 'c', 'd', 'f', 'h'] ['b', 'c', 'd', 'g', 'h'] ['b', 'c', 'e', 'f', 'h'] ['b', 'c', 'e', 'g', 'h']
Now I have found a solution, but this is not satisfactory for me:
def all_paths(s, acc=None, result=None):
As you can see, this is due to copying the list of TWICE drives, for a fairly obvious reason, that if the method of the .append () or .extend () method is called from the recursion stack, the battery will be modified, because it is passed by label (separation in the official lingui?).
I tried to build a solution that pop () s and append () s the relevant number of elements is disconnected from the battery, but cannot get it correctly:
def all_p(s, acc=None, result=None, calldepth=0, seqlen=0): if acc is None: acc = [] if result is None: seqlen = len(s) result = [] head, tail = s[0], s[1:] for el in head: acc.append(el) if tail: all_p(tail, acc=acc, result=result, calldepth=calldepth+1, seqlen=seqlen) else: result.append(acc[:]) print acc for i in xrange(1+seqlen-calldepth): acc.pop() return result
Result:
['a', 'c', 'd', 'f', 'h'] ['a', 'c', 'd', 'g', 'h'] ['a', 'c', 'd', 'e', 'f', 'h'] ['a', 'c', 'd', 'e', 'g', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'f', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'g', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'e', 'f', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'e', 'g', 'h'] ['a', 'c', 'd', 'f', 'h'] ['a', 'c', 'd', 'g', 'h'] ['a', 'c', 'd', 'e', 'f', 'h'] ['a', 'c', 'd', 'e', 'g', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'f', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'g', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'e', 'f', 'h'] ['a', 'c', 'd', 'e', 'b', 'c', 'd', 'e', 'g', 'h']
Obviously, this is due to the fact that as a depth recursion, there is a switch up and down the call chain, and I can not get the number pop () s to finish the list of batteries.
I understand that this is a little practical gain, since copying the list is O (n), while popping k elements from the list O (k), so there are not many differences, but I'm curious if this can be done.
(Background: I update the phonecode test code, http://page.mi.fu-berlin.de/prechelt/phonecode/ , and this is the part that finds all the words, but each fraction of the phone number can be displayed for several words, for example :
... '4824': ['fort', 'Torf'], '4021': ['fern'], '562': ['mir', 'Mix'] ...
so I need to find all possible "paths" through the selected list of matching words and / or numbers corresponding to the specified phone number)
Questions, requests:
Can I fix a version that does not copy the battery?
is there a solution for this that uses the itertools module?
Any other, better approach to this particular problem? how is a non-recursive solution, faster solution, less memory intensive?
Yes, I know this is a load problem, but if someone solves a non-empty part of them, I would be grateful. :-)