# [Tutor] Need help combining elements of a list of lists

Jim jf_byrnes at comcast.net
Wed Jul 11 12:09:57 EDT 2018

On 07/10/2018 11:03 PM, Mats Wichmann wrote:
> On 07/10/2018 09:09 PM, Steven D'Aprano wrote:
>> On Tue, Jul 10, 2018 at 09:46:57PM -0500, Jim wrote:
>>
>>> Say I have a list like ltrs and I want to print out all the possible 3
>>> letter combinations. I want to combine letters from each inner list but
>>> not combine any letters within the inner list itself. So ACF and ADF
>>> would be ok but ABC would not.
>>>
>>> I can lay it out manually and see the pattern, I cannot figure out how
>>> to do it programically. Just in case this looks like homework it is not.
>>> It's a small test case I devised to try to figure it out so I can apply
>>> it to a bigger real world problem I am working on.
>>>
>>> ltrs = [['A', 'B'], ['C', 'D', 'E'], ['F', 'G', 'H', 'I']]
>>
>> If you know that there are just three sublists, then you can do this:
>>
>> for a in ltrs[0]:
>>      for b in ltrs[1]:
>>          for c in ltrs[2]:
>>              print(a + b + c)
>>
>> I trust that's easy enough to understand.
>>
>> But here's a more general technique, where you don't need to know up
>> front how many nested lists there are:
>>
>>
>> from itertools import product  # short for "Cartesian Product"
>> for s in product(*ltrs):
>>      print(''.join(s))
>
> This is one of those cases where: if it's homework, getting the nested
> loops right is almost certainly the way to go.  If it isn't, then
> itertools (that is, "using an available library solution") is almost
> certainly the way to go :)
>
> If the eventual case is not just "letters", and a list of combined lists
> is the eventual goal, then the concise stanza is:
>
> prods = list(product(*ltrs))
>
> print(prods) then gives you:
>
> [('a', 'c', 'f'), ('a', 'c', 'g'), ('a', 'c', 'h'), ('a', 'c', 'i'),
> ('a', 'd', 'f'), ('a', 'd', 'g'), ('a', 'd', 'h'), ('a', 'd', 'i'),
> ('a', 'e', 'f'), ('a', 'e', 'g'), ('a', 'e', 'h'), ('a', 'e', 'i'),
> ('b', 'c', 'f'), ('b', 'c', 'g'), ('b', 'c', 'h'), ('b', 'c', 'i'),
> ('b', 'd', 'f'), ('b', 'd', 'g'), ('b', 'd', 'h'), ('b', 'd', 'i'),
> ('b', 'e', 'f'), ('b', 'e', 'g'), ('b', 'e', 'h'), ('b', 'e', 'i')]
>
> if you want them concatenated, then of course join is the way to do that.
>
>
>

Steven & Mats thanks for your replies.

It is more that just letters. I was reading Al Sweigart's book Cracking
Codes with Python. I got to the chapter on substitution cyphers and
wondered if his program could solve the daily Crypto Quips in the
newspaper. Turns out it did not do a very good job because the quips
were to short.

It did produce a dictionary where the keys are the letters of the
alphabet and the items are a list of possible letters to substitute. If
a key has no possible letters it is ignored, if a key has only one
possible letter it considered a solution and plugged into the cypher.
the keys with multiple possible letters are ones I am interested in.

I know you cannot brute force a substitution cypher but maybe I could
loop over and combine the possible substitution letters and crack it
that way. That's why I made up the letter problem, I wanted to see how
to do it on a simple data set before attempting much more complex one.

It looks like the library solution is the way for me to try.

Regards,  Jim