web-dev-qa-db-ja.com

Pythonで文字列のすべての連続した部分文字列を取得する方法は?

ここに私のコードがありますが、より良い解決策が欲しいのですが、問題についてどう思いますか?

def get_all_substrings(string):
  length = len(string)
  alist = []
  for i in xrange(length):
    for j in xrange(i,length):
      alist.append(string[i:j + 1]) 
  return alist

print get_all_substring('abcde')
34
lqhcpsgbl

私が考えることができる唯一の改善は、このようなリストの理解を使用することです

def get_all_substrings(input_string):
  length = len(input_string)
  return [input_string[i:j+1] for i in xrange(length) for j in xrange(i,length)]

print get_all_substrings('abcde')

あなたと私のタイミングの比較

def get_all_substrings(string):
  length = len(string)
  alist = []
  for i in xrange(length):
    for j in xrange(i,length):
      alist.append(string[i:j + 1]) 
  return alist

def get_all_substrings_1(input_string):
  length = len(input_string)
  return [input_string[i:j + 1] for i in xrange(length) for j in xrange(i,length)]

from timeit import timeit
print timeit("get_all_substrings('abcde')", "from __main__ import get_all_substrings")
# 3.33308315277
print timeit("get_all_substrings_1('abcde')", "from __main__ import get_all_substrings_1")
# 2.67816185951
41
thefourtheye

あなたがする必要がない場合、一度にメモリにすべての文字列を保存することを節約するジェネレータとしてそれを書くことができます

def get_all_substrings(string):
    length = len(string)
    for i in xrange(length):
        for j in xrange(i + 1, length + 1):
            yield(string[i:j]) 

for i in get_all_substrings("abcde"):
    print i

本当に必要な場合でもリストを作成できます

alist = list(get_all_substrings("abcde"))

関数はジェネレータ式を返すように縮小できます

def get_all_substrings(s):
    length = len(s)
    return (s[i: j] for i in xrange(length) for j in xrange(i + 1, length + 1))

または、もちろん、メモリを気にしない場合は、2文字を変更してリストを返すことができます

def get_all_substrings(s):
    length = len(s)
    return [s[i: j] for i in xrange(length) for j in xrange(i + 1, length + 1)]
9
John La Rooy

私はrange(len(seq))が好きではありません。enumerateを使用して、インデックス値を使用する方法はどうですか:

def indexes(seq, start=0):
    return (i for i,_ in enumerate(seq, start=start))

def gen_all_substrings(s):
    return (s[i:j] for i in indexes(s) for j in indexes(s[i:], i+1))

def get_all_substrings(string):
    return list(gen_all_substrings(string))

print(get_all_substrings('abcde'))
6
PaulMcG

itertools.combinationsで簡潔に行うことができます

from itertools import combinations

def get_all_substrings_2(string):
    length = len(string) + 1
    return [string[x:y] for x, y in combinations(range(length), r=2)]
4
DyRuss

Python 3

s='abc'
list(s[i:j+1] for i in range (len(s)) for j in range(i,len(s)))

['a', 'ab', 'abc', 'b', 'bc', 'c']
3
user4043951

つかいます itertools.permutations可能な開始インデックスと終了インデックスのすべてのペアを生成し、開始インデックスが終了インデックスよりも小さいインデックスのみを除外します。次に、これらのペアを使用して、元の文字列のスライスを返します。

from itertools import permutations

def gen_all_substrings(s):
    lt = lambda pair: pair[0] < pair[1]
    index_pairs = filter(lt, permutations(range(len(s)+1), 2))
    return (s[i:j] for i,j in index_pairs)

def get_all_substrings(s):
    return list(gen_all_substrings(s))

print(get_all_substrings('abcde'))
0
PaulMcG

2Dマトリックスアプローチを使用する別のソリューション

p = "abc"
a = list(p)
b = list(p)
c = list(p)
count = 0
for i in range(0,len(a)):
       dump = a[i]
            for j in range(0, len(b)):
                if i < j:
                    c.append(dump+b[j])
                    dump = dump + b[j]  
0
Nkromin989

別の解決策:

def get_all_substrings(string):
   length = len(string)+1
   return [string[x:y] for x in range(length) for y in range(length) if string[x:y]]

print get_all_substring('abcde')
0
sanooj