文字列のターゲットリストから引き出すために使用している名前のリストがあります。例えば:
names = ['Chris', 'Jack', 'Kim']
target = ['Chris Smith', 'I hijacked this thread', 'Kim','Christmas is here', 'CHRIS']
output = ['Chris Smith', 'Kim', 'CHRIS']
したがって、これまでのルールは次のとおりです。
- 大文字小文字を区別しません
- 部分的な単語と一致することはできません(つまり、クリスマス/ハイジャックされたものはクリス/ジャックと一致しないはずです)
- 上記の基準に従って文字列に名前が含まれている限り、文字列内の他の単語は問題ありません。
これを達成するために、別のSOユーザーがこのスレッドでこのコードを提案しました:
[targ for targ in target_list if any(re.search(r'\b{}\b'.format(name), targ, re.I) for name in first_names)]
これはこれまでのところ非常に正確に機能しますが、名前リストの長さが最大5,000で、ターゲットリストの長さが20〜100行で、文字列の長さが30文字までの場合は非常に遅くなります。
ここでパフォーマンスを改善する方法について何か提案はありますか?
解決策:両方の正規表現ベースの解決策でオーバーフローエラーが発生したため、残念ながらテストできませんでした。(@mglisonの回答から)機能した解決策は次のとおりです。
new_names = set(name.lower() for name in names)
[ t for t in target if any(map(new_names.__contains__,t.lower().split())) ]
これにより、パフォーマンスが15秒から1秒未満に大幅に向上しました。