1

someStr で 'x'、'y'、'z' のいずれかの文字の最初の出現を見つけるより良い方法はありますか?

def findFirstAppearance(someStr):
    x = someStr.find('x');
    y = someStr.find('y');
    z = someStr.find('z');

    if x == -1: x= len(someStr);
    if y == -1: y= len(someStr);
    if z == -1: z= len(someStr); 

    return min(x,y,z);

例: someStr = "axby" の場合は 1 を返す必要があります。someStr = "aybx" の場合も 1 を返す必要があります。

ありがとう!

4

6 に答える 6

2

多分:

>>> s = 'this string x contains y several letters z'
>>> next(i for i,c in enumerate(s) if c in 'xyz')
12
>>> s[12]
'x'

見つからない場合は例外が発生しますが、これはデフォルト値を使用して修正できます。

>>> next(i for i,c in enumerate(s) if c in 'Q')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next((i for i,c in enumerate(s) if c in 'Q'), -1)
-1

次のメンバーシップをテストするセットを事前に構築することもできます。

>>> special = set("vmp")
>>> next((i for i,c in enumerate(s) if c in special), -1)
27

テストする文字がたくさんある場合は、より高速になる可能性があります。関連するサイズに大きく依存します。問題があれば簡単に実験できますが、(ネタバレ注意)おそらくそうではありません。

于 2013-03-27T15:28:48.723 に答える
1

正規表現を使用した代替方法を次に示します。

import re
def find_first_dx(needles, haystack):
    match = re.search('|'.join(map(re.escape, needles)), haystack)
    return match.start() if match else -1

例:

>>> find_first_dx('xyz', 'abcyax')
3
>>> find_first_dx('xyz.', 'a.bcyax')
1
>>> find_first_dx('xyz', 'fee fi foe fum')
-1
>>> find_first_dx(['foe', 'fum'], 'fee fi foe fum')
7
于 2013-03-27T16:01:02.647 に答える
0

これはうまくいくはずです:

def findany(s1, s2):
    for i, x in enumerate(s1):
        if x in s2:
            return i
    return -1
于 2013-03-27T15:36:37.060 に答える
0

これがあなたが探しているものだと思います。これは、5 つの文字 ( ) のいずれかが文字列内で最初に出現する場所を見つけitemsます。のように機能しstr.findます。

def findany(string, items, start, end=-1):
    if end == -1:
        end = len(string)

    for i in range(start, end):
        c = string[i]
        if c in items:
            return i

    return -1

#      01234567
inp = "hellozxy"

print findany(inp, "xyz")    # 5 = z
print findany(inp, "?")      # -1 = not found
print findany(inp, ["o", "l"], 3)    # 3, skips the first 'l'

注: 文字 (1 文字の文字列) のリストを として渡しますitems。Pythonでは、文字列はまさにそれです。["x", "y", "blah"] のようなものを渡すと、機能しません ("blah" は無視されます)。

于 2013-03-27T15:27:30.620 に答える
0

を使用するenumerate()と、文字列の各文字のタプルが生成されます。

タプルの最初の要素はインデックスで、2 番目の要素は文字そのものです。

In [103]: def find_first(strs):
   .....:     for i,x in enumerate(strs):
   .....:         if x in 'xyz': #if current character is either
                                 #'x' or 'y' or 'z' then return index
   .....:             return i
   .....:     return -1              #if the loop completed successfully then return -1
   .....: 

In [104]: find_first("fooxbaryzx")
Out[104]: 3

In [105]: find_first("qwerty")
Out[105]: 5

In [106]: find_first("qwert")
Out[106]: -1

In [107]: find_first("axby")
Out[107]: 1

In [108]: find_first("aybx")
Out[108]: 1
于 2013-03-27T15:29:32.033 に答える
0

多くの文字については、特にアプリケーションのループでこれを行っている場合は、正規表現の使用について真剣に検討する必要があります。

import re
def findall(string, chars)
    m = re.search("[%s]" % chars, string, re.DOTALL)
    if m:
        return m.start()
    return -1

これは、文字ごとに "find" を呼び出す純粋な Python ループよりも少なくとも 100 倍高速になるはずです。

正規表現 "[ ]" 内で他の目的に使用される文字を見つける必要がある場合は、それらをエスケープする必要があることに注意してください ("-"、"^" など)。

于 2013-03-27T15:52:55.780 に答える