2016-07-18 5 views
2

長い文字列の別の部分に存在する場合、リスト内の短い文字列の1つを返すようにします。どうしますか?Pythonのリストから一致するアイテムを返す方法

これは私の頭に現れていることですが、Pythonでfuncを実装するより良い方法がありますか?あなたがもし句でジェネレータ式を使用することができます

>>> def func(shortStrList, longStr): 
...  return shortStrList[[x in longStr for x in shortStrList].index(True)] 
... 
>>> func(['ABC', 'DEF', 'GHI'], 'PQRABCD') 
'ABC' 
>>> func(['ABC', 'DEF', 'GHI'], 'DEFPQRACD') 
'DEF' 
+0

あなたが '、 'FUNC([ 'ABC'、 'DEF'、 'GHI']の出力を何を期待しABCDEF ') 'は? – DeepSpace

+1

私には十分にピジョンがあるようです。 – Eduard

+0

@DeepSpace「ABC」を返すのが好きです。すなわち、最初のマッチ – Porz

答えて

2

の回答/コメントを統合するには、別の回答のパフォーマンスに簡単なテストを行うことを願って...

>>> def timeTest(s, f): 
...  t1 = time.clock() 
...  for x in xrange(s): 
...   f(['ABC', 'DEF', 'GHI'], 'PQRABCD') 
...   f(['ABC', 'DEF', 'GHI'], 'PQRACDEF') 
...   f(['ABC', 'DEF', 'GHI'], 'PGHIQRCD') 
...  t2 = time.clock() 
...  print t2 - t1 
... 
>>> 
>>> def func1(shortStrList, longStr): 
...  return shortStrList[[x in longStr for x in shortStrList].index(True)] 
... 
>>> timeTest(10000000, func1) 
18.4710161502 
>>> 
>>> def func2(shortStrList, longStr): 
...  return next(s for s in shortStrList if s in longStr) 
... 
>>> timeTest(10000000, func2) 
26.1494262581 
>>> 
>>> def func3(shortStrList, longStr): 
...  filter(lambda x: x in longStr, shortStrList)[0] 
... 
>>> timeTest(10000000, func3) 
26.1221138429 
>>> 
>>> def func4(shortStrList, longStr): 
...  for s in shortStrList: 
...   if s in longStr: return s 
... 
>>> timeTest(10000000, func4) 
8.78067844999 
>>> 
>>> def func5(shortStrList, longStr): 
...  return [string for string in shortStrList if string in longStr][0] 
... 
>>> timeTest(10000000, func5) 
12.549210555 
>>> 

は、ループをやっように思えます(func4)としてEkeyme Moが最速です。 (これは1つのライナーとして書き直すことができるかどうかはわかりません)

短い文字列リストの長さが異なる場合、異なる方法が好まれるかもしれません。 シンプルループは最も速く実行されますが、next()はリストが長いときにリスト内包より速く実行します。

>>> def timeTest(s, f): 
...  sl = ['ABC'] + ['ZXYZ']*50 + ['DEF'] + ['RQDSF']*50 + ['GHI'] 
...  t1 = time.clock() 
...  for x in xrange(s): 
...   f(sl, 'PQRABCD') 
...   f(sl, 'PQRACDEF') 
...   f(sl, 'PGHIQRCD') 
...  t2 = time.clock() 
...  print t2 - t1 
...  
>>> def func1(shortStrList, longStr): 
...  return shortStrList[[x in longStr for x in shortStrList].index(True)] 
... 
>>> timeTest(100000, func1) 
2.14106761862 
>>> 
>>> def func2(shortStrList, longStr): 
...  return next(s for s in shortStrList if s in longStr) 
... 
>>> timeTest(100000, func2) 
0.867831158122 
>>> 
>>> def func3(shortStrList, longStr): 
...  filter(lambda x: x in longStr, shortStrList)[0] 
...  
>>> timeTest(100000, func3) 
3.19491244615 
>>> 
>>> def func4(shortStrList, longStr): 
...  for s in shortStrList: 
...   if s in longStr: return s 
...   
>>> timeTest(100000, func4) 
0.629572839949 
>>> 
>>> def func5(shortStrList, longStr): 
...  return [string for string in shortStrList if string in longStr][0] 
... 
>>> timeTest(100000, func5) 
1.31148152449 
>>> 
+1

と1つです。回答の統合に関する素晴らしいベンチマーク。確かに他の人を助けるだろうか? –

+1

ニースの比較。 Pythonドキュメントが示唆しているように、ベンチマークのために['time.clock'](https://docs.python.org/2/library/time.html#time.clock)を使いたいかもしれません。 – niemmi

4

:好みの問題について

def func(shortStrList, longStr): 
    return next(s for s in shortStrList if s in longStr) 
0

あなたが好きなら、あなたの代わりに、リストの内包表記のfilterを使用することができます。

def func(shortStrList, longStr): 
    filter(lambda x: x in longStr, shortStrList)[0] 
func(['ABC', 'DEF', 'GHI', 'JDSLDF'], 'PQRABCD') 
# ABC 

はそれが役立ちます:)

+1

ラムダ関数の代わりに 'e .__ contains__'を使うことができます。 –

+0

ええ、そうです。 –

0

あなたはそれが簡単で、このように維持することができます:

def func(shortStrList, longStr): 
    try: 
     return [string for string in shortStrList if string in longStr][0] 
    except IndexError: 
     return("No matches found") 

出力:

>>> func(['ABC', 'DEF', 'GHI'], 'PQRABCD') 
'ABC' 
>>> func(['ABC', 'DEF', 'GHI'], 'DEFPQRACD') 
'DEF' 
>>> func(['ABC', 'DEF', 'GHI'], 'ABCDEF') 
'ABC' 

ます。また、リスト内包せずに、このようにそれを行うことができます。これは、最初の解決策が見つかるとすぐに停止します。最も最も簡単な方法です

def func2(shortStrList, longStr): 

    result = "" 
    for string in shortStrList: 
     if string in longStr: 
      result += string 
      break 
    else: 
     return("No matches found") 

    return result 

、あるいはこのよう、:

def func3(shortStrList, longStr): 
    result = [] 
    for string in shortStrList: 
     if string in longStr: 
      result.append(string) 
    else: 
     print("No matches found") 

    return result[0] 
関連する問題