1

In python 3, I have a variable length list, where each element of the list is a variable length string. Something like this

['TO', 'G', 'ZDO', 'DEO', 'SGT', 'D', 'Z', 'FT', 'OV']

and I want to iterate over every possible combination of words where the letters that make up the word are from the strings in the list, and the length of the word is the same as the length of the list. So something like this

TGZDSDZFO
TGZDSDZFV
TGZDSDZTO
...
OGOOTDZTO
OGOOTDZTV

I am having trouble coming up with a generic solution for n-sized list.

2
  • How do you know how many characters to extract for every string in the list Commented Dec 16, 2014 at 18:58
  • Time, I want one character at a time from each string. Each string in the list contains the possible characters that make up the word at that position in the word. Commented Dec 16, 2014 at 18:59

3 Answers 3

8
>>> (''.join(s) for s in itertools.product(*['TO', 'G', 'ZDO', 'DEO', 'SGT', 'D', 'Z', 'FT', 'OV']))
<generator object <genexpr> at 0x7f2a46468f00>
>>> # to demonstrate:
... 
>>> list(itertools.islice((''.join(s) for s in itertools.product(*['TO', 'G', 'ZDO', 'DEO', 'SGT', 'D', 'Z', 'FT', 'OV'])), 3))
['TGZDSDZFO', 'TGZDSDZFV', 'TGZDSDZTO']
Sign up to request clarification or add additional context in comments.

1 Comment

itertools.product() does the product of all of its arguments. The * separates the list into separate arguments for the function call. ''.join() joins with no separators. The rest is just a normal genex.
2

As others have suggested, itertools is perhaps the simplest/easiest way to solve this. If you are looking to write your own algorithm however (i.e. reimplement what itertools does under the hood), then take a look at this:

def allPerms(L, sofar=''):
    if not L:
        print(sofar)
    else:
        for char in L[0]:
            allPerms(L[1:], sofar+char)

Output:

In [97]: L = ['TO', 'G', 'ZDO', 'DEO', 'SGT', 'D', 'Z', 'FT', 'OV']

In [98]: allPerms(L)
TGZDSDZFO
TGZDSDZFV
TGZDSDZTO
TGZDSDZTV
TGZDGDZFO
TGZDGDZFV
TGZDGDZTO
TGZDGDZTV
TGZDTDZFO
TGZDTDZFV
TGZDTDZTO
TGZDTDZTV
TGZESDZFO
TGZESDZFV
TGZESDZTO
TGZESDZTV
TGZEGDZFO
TGZEGDZFV
TGZEGDZTO
TGZEGDZTV
--- truncated ---

EDIT:

As @njzk2 points out, python3's yield-from does a fantastic job of making the output usable:

def allPerms(L, sofar=''):
    if not L: yield sofar
    else:
        for char in L[0]: yield from allPerms(L[1:], sofar+char)

Output:

In [118]: for i in allPerms(L): print(i)
TGZDSDZFO
TGZDSDZFV
TGZDSDZTO
TGZDSDZTV
TGZDGDZFO
TGZDGDZFV
TGZDGDZTO
TGZDGDZTV
TGZDTDZFO
TGZDTDZFV
TGZDTDZTO
TGZDTDZTV
TGZESDZFO
TGZESDZFV
TGZESDZTO
TGZESDZTV
TGZEGDZFO
TGZEGDZFV
TGZEGDZTO
TGZEGDZTV
TGZETDZFO
TGZETDZFV
TGZETDZTO
--- truncated ---

3 Comments

yield would be nicer than print, as it would allow to use the output.
I am trying as well, no luck so far. I'll let you know when I get there.
this stackoverflow.com/a/6755918/671543 explains that before python 3, we need to re-iterate to transmit the yield, but in python 3 we can use yield from, which yields successively all items. python2 -> yield sofar + for value in allPerms(L[1:], sofar+char): yield value, python3 -> yield sofar + yield from allPerms(L[1:], sofar+char)
-4

you could use the itertools module to create the permutations of your desired length. combine all the workds to one string and use it in the permutations function

lst = ['TO', 'G', 'ZDO', 'DEO', 'SGT', 'D', 'Z', 'FT', 'OV']
length = len(lst)

combined = ''.join(lst)
all_perms = itertools.permutations(combined, length)
#this will give you something like [('T', 'O', ...), (...),]

print ([''.join(x) for x in all_perms])

5 Comments

I don't think permutations is appropriate here
please explain why not
Did you run this code? Did you compare the output to OP's requested output?
@CCKx because it does not yield the expected output, for starters.
@njzk2, agreed.I did not read OP's reply to the comment by Tim Castelijns. itertools.product makes much more sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.