次のようなアルファベット順の名前のリストがあります。
list = ['ABC', 'ACE', 'BED', 'BRT', 'CCD', ..]
各開始文字から要素を取得するにはどうすればよいですか? リストを 1 回反復する必要がありますか? またはpythonにはそれを行うための機能がありますか?Python は初めてなので、これは非常に素朴な問題かもしれません。
「A」から始まる名前から 2 番目の要素を取得したいとします。この場合、「ACE」を取得します。
すべての要素を最初の文字でグループ化するだけです
from itertools import groupby
from operator import itemgetter
example = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']
d = {g:list(values) for g, values in groupby(example, itemgetter(0))}
次に、a で始まる値を取得します。
print d.get('A', [])
これは、静的リストがあり、複数のクエリがある場合に最も便利です。ご覧のとおり、「A」で始まる 3 番目の項目の取得は O(1) で行われるためです。
リスト内包表記を使用したい場合があります
mylist = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']
elements_starting_with_A = [i for i in mylist if i[0] == 'A']
>>> ['ABC', 'ACE']
second = elements_starting_with_A[1]
>>> 'ACE'
簡単な解決策は、リスト全体を反復処理することですO(n)
。
(name for name in names if name.startswith('A'))
O(log(n))
ただし、名前を並べ替えて、インデックスまたはその後にあるはずのアイテムを検索することはできます(辞書式比較を使用)。このモジュールbisect
は境界を見つけるのに役立ちます:
from bisect import bisect_left
names = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']
names.sort()
lower = bisect_left(names, 'B')
upper = bisect_left(names, chr(1+ord('B')))
print [names[i] for i in range(lower, upper)]
# ['BED', 'BRT']
他の人が言及したリストの理解に加えて、リストにはsort()
メソッドもあります。
mylist = ['AA', 'BB', 'AB', 'CA', 'AC']
newlist = [i for i in mylist if i[0] == 'A']
newlist.sort()
newlist
>>> ['AA', 'AB', 'AC']