0

I have a simple string "abc". Now I have to write Python code for creating all possible unique substrings, except the empty string, from this string.

The answer should be as follows: a b c ab ac bc abc

I wrote something like this :

def getsubstrings(str):
    sub = []
    length = len(str)
    for i in range(length):
        for j in range(i,length):
            sub.append(str[i:j+1])
    sub.sort()
    return sub

str = "abc"
print (getsubstrings(str))

But this is probably the wrong way , since it is not giving expected results.

Can someone please help me with an efficient solution.

Thanks in advance.

Bill Bell
  • 21,021
  • 5
  • 43
  • 58
Subhayan Bhattacharya
  • 5,407
  • 7
  • 42
  • 60
  • the `itertools` modules has a function that does that. – njzk2 Apr 14 '17 at 14:13
  • 1
    You are looking for [`itertools.permutation`](https://docs.python.org/library/itertools.html#itertools.permutations). – metatoaster Apr 14 '17 at 14:13
  • 1
    Possible duplicate of [How to generate all permutations of a list in Python](http://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python) – shizhz Apr 14 '17 at 14:16
  • 4
    Why is everyone talking about permutations? The OP explains his desired output, and it doesn't include anything like "ba" or "cab". – DSM Apr 14 '17 at 14:19

3 Answers3

3

The build-in itertools library (https://docs.python.org/3.6/library/itertools.html) has some wonderful functions that you can use. Basically you want to get the possible combinations of letters, for different length of strings.

So the code sample below loops over the size of the string: (1,2,3), gets all possible combinations for that particular size, and "chains", or appends them. The functions from itertools use iterators, which means that the final answer isn't stored in memory, but created when you need the values. For larger strings this will use much less RAM.

from itertools import chain, combinations
s='abc'
list(chain(*[combinations(s,x) for x in range(1,len(s)+1)]))

>>> [('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'b', 'c')]
Peter Smit
  • 1,594
  • 1
  • 13
  • 27
1

combnations will help you to achieve the result

data= 'abc'
from itertools  import combinations

for num in xrange(1,len(data)+1):
    for i in combinations(data,num):
        print ''.join(i)

a
b
c
ab
ac
bc
abc     
blacksite
  • 12,086
  • 10
  • 64
  • 109
galaxyan
  • 5,944
  • 2
  • 19
  • 43
0

Use itertool combinations to create combinations of different length.

>>> from itertools import combinations
>>> s = "abc"
>>> result = []
>>> for l in range(1, len(s)+1):
...     for c in combinations(s,l):
...         result.append(c)
... 
>>> print result
[('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'b', 'c')]

You can later change format of result, for example:

>>> result = [''.join(r) for r in result]
>>> print result
['a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']
Mateusz Knapczyk
  • 276
  • 1
  • 2
  • 15