1

文字列がリストの項目で順番に形成できるかどうかを検出する if ステートメントを作成したいと思います。たとえば、用語が「HelloWorld」と同じ意味を持っているかどうかを確認したい場合は、「hello」リストに を['hello', 'Hello', 'Hi', 'Greetings', 'Hola']、「world」リストに を使用し['world', 'World', 'Planet', 'Earth']ます。次に、文字列が「hello」リストの任意の項目の直後に「world」リストの任意の項目が続くかどうかを確認します。「HelloWorld」、「GreetingsEarth」、および「HiPlanet」はすべて、if ステートメントを正常にトリップします。どうすればいいですか?Python のリストを使いたいので、正規表現 (a|b) は実用的ではないようです。

4

4 に答える 4

4

正規表現を避けたい場合は、各組み合わせをテストするジェネレーター式を使用できます ( によって生成されますitertools.product)。

import itertools
combinations = (''.join((first, second)) for first, second in itertools.product(a, b))
any('HelloWorld' == combination for combination in combinations)

これは正規表現のアプローチよりもはるかに遅いことに注意してください。特に、最悪のシナリオ (一致しない) に遭遇した場合はそうです。

>>> timeit.timeit('search("HelloWorld"); search("HiThere")', 'from __main__ import reMatch as search')
1.8922290802001953
>>> timeit.timeit('search("HelloWorld"); search("HiThere")', 'from __main__ import genMatch as search')
18.3697190284729

ジェネレーター式は、正規表現アプローチよりも 10 倍遅くなります。

(re.compile()テストにはコンパイル済みの正規表現を使用しました)。

于 2012-09-22T18:41:32.547 に答える
2

正規表現は問題なく機能します。

a = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
b = ['world', 'World', 'Planet', 'Earth']

import re
r = '^(%s)(%s)$' % ('|'.join(a), '|'.join(b))

print re.match(r, "HelloWorld").groups() # ('Hello', 'World')
print re.match(r, "HiThere") # None

正規表現以外のソリューションは面倒です:

s = "GreetingsEarth"
for x in a:
    if s.startswith(x) and s[len(x):] in b:
        print x, '+', s[len(x):]
        break 
于 2012-09-22T18:36:42.383 に答える
2

これは実際には、次のように正規表現で行うことができます。

list1 = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
list2 = ['world', 'World', 'Planet', 'Earth']
regex = "(%s)(%s)" % ("|".join(list1), "|".join(list2))
print re.match(regex, "HelloWorld")

しかし、次のようにすることもできますitertools.product:

print any("HelloWorld" == x + y for x, y in itertools.product(list1, list2)) 
于 2012-09-22T18:36:53.127 に答える
1

2 番目のリストにセットを使用しているので、すべてのアイテムを毎回繰り返す必要はありません。

a = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
b = ['world', 'World', 'Planet', 'Earth']

b_set = set(b)
needle = 'HelloWorld'
for start in a:
    if needle.startswith(start) and needle[len(start):] in b_set:
         print 'match'

短いバージョンをお探しの場合

any((needle[len(start):] in b_set for start in a if needle.startswith(start)))

対照的に、itertools.productこの解決策はすべての可能な組み合わせを比較する必要はありませんがn^2、最初のリスト ( n) を 1 回だけ見て、最悪の場合は追加のセット ルックアップを実行する必要があります。

于 2012-09-22T18:50:47.783 に答える