2016-11-16 3 views
0

私は約90k要素(約670ユニーク)のリストを持っています。私は各値の最初の出現のためのインデックスを取得したいと思います。リスト内の各要素が最初に出現するインデックスを取得しますか?

In: [["foo", "bar", "baz", "bar", "foo"].index(x) for x in ["foo", "bar", "baz", "bar", "foo"]] 
Out: [0, 1, 2, 1, 0] 

これは動作しますが、それは私のマシン上で実行するために数分かかります:私はちょうどこのようにリストの内包を試してみました。これを行うためのより良い(より速い)方法は何ですか?

+0

あなたが探していますリスト内の項目を列挙するか?その場合は、 'enumerate([" "foo"、 "bar"、 "baz"、 "bar"、 "foo"]) 'を使用します。 – vaultah

+0

私はリストを列挙しようとしていません、私は最初のオカレンスのインデックスを取得するために探しています。私は私の質問を修正するつもりです。 – Nate

+0

出力を '[0,1,2,1,0]'または重複しないようにしますか? –

答えて

2

は、私はあなただけ(あなたがリストの各項目のうち最初に出現した場合を除き)enumerateを使用したいと思う:

strings = ["foo", "bar", "baz", "bar", "foo"] 
for index, value in enumerate(strings): 
    print index, value 

出力を

0 foo 
1 bar 
2 baz 
3 bar 
4 foo 

あなたが望んでいた場合は、例えば、1 bar3 barの代わりに、見つかった文字列の辞書を維持することができます。

for index, value in enumerate(strings): 
    if value not in d: 
     d[value] = index 

for value in strings: 
    print value, d[value] 
+0

@Chris_Rands、私は実際に最初のオカレンス(前によく書かれていない私の質問/タイトル) – Nate

+1

これは、OPによって投稿された例ではうまく動作しますが、90k要素と600の一意の値を持つリストに対しても同様に機能しません。 –

+0

@ Ev.Kounisいくつかのことはちょうど時間がかかる。ハッシュ値を比較してセット内の重複を識別することを改善することはあまりありません。 – chepner

2

あなたの質問は非常に曖昧ですが、私はそれを理解しているので、重複した値が多く、それぞれの最初の外観のインデックスを取得したいだけです。そうmy_list_unique内のすべてのエントリが一度だけ存在する3行目のセットの作成は重複を取り除くこと

my_list = ["foo", "bar", "baz", "bar", "foo"] 

my_list_unique = set(my_list) 
indexes = [(x, my_list.index(x)) for x in my_list_unique] 
print(indexes) # prints -> [('foo', 0), ('bar', 1), ('baz', 2)] 

注:私はこのようなセットを活用します。これにより、索引を探す時間を節約できます。結果が出る限り、各タプルには最初に見つかった文字列とインデックスが含まれるタプルのリストですmy_list

+0

は、4行目のリストの理解ではなく、約670回分の90kの長さのリストを通して繰り返しますか? – maahl

+0

大きなリストは90k長であり、4行目のリストの理解は 'my_list_unique'を繰り返します。これはわずか670です。 –

+0

はい、しかし、 'my_list.index()'も 'my_list'を反復しなければなりません...現在の' x'の最初の出現までですが、それでも無視できません。 – maahl

2

各単語の最初の出現のインデックスを格納する辞書を構築できます。 そのようにすれば、あなたは大きなリストを1回だけ見るだけで、ディクショナリは各値を1回しか含まず、O(log(n))でアクセスされるので、辞書ルックアップはずっと高速です。あなたは出力に元のリストの各要素に対して最初に出現する位置のインデックスを含む90K-長いリストが必要な場合は

l = ["foo", "bar", "baz", "bar", "foo"] 
v = {} 
for i, x in enumerate(l): 
    if x not in v: 
     v[x] = i 

# v is now {'bar': 1, 'baz': 2, 'foo': 0} 

また、あなたはそのようにそれを得ることができます。

output = [v[x] for x in l] 
# output is now [0, 1, 2, 1, 0] 
関連する問題