1

ユーザーがサイトのリストにアクセスしたかどうかを確認するために、プロキシ ログを調べなければならないという問題に遭遇しました。

訪問したホストをリストと照合して、すべてのプロキシ ログを読み取る小さなスクリプトを作成しました。

for proxyfile in proxyfiles:
    for line in proxyfile.readlines():
        if line[4] in hosts_list:
            print line

hosts_file は大きく、約 10000 のホストについて話しているのですが、検索に予想以上に時間がかかることに気付きました。

私は小さなテストを書きました:

import random, time
test_list = [x for x in range(10000)]
test_dict = dict(zip(test_list, [True for x in range(10000)]))

def test(test_obj):
 s_time = time.time()
 for i in range(10000):
  random.randint(0,10000) in test_obj
 d_time = time.time() - s_time
 return d_time

print "list:", test(test_list)
print "dict:",test(test_dict)

結果は次のとおりです。

list: 5.58524107933
dict: 0.195574045181

それで、私の質問に。この検索をより便利な方法で実行することは可能ですか? リストに含まれる値ではなくキーを検索したいので、リストの辞書を作成するのはハックのようです。

4

3 に答える 3

5

「含まれている値ではなく、キーを検索したいので」 =>次に使用しますset

于 2012-06-04T13:20:27.693 に答える
2

そのようなことには辞書を使用し、新しい python に設定し、アプリケーションで可能であれば 2.2 よりも新しい python に移行することを検討する必要があることに同意します。

ただし、リストがソートされている場合は、bisect モジュールを使用してリストをすばやく検索し、要素を見つけることができます。辞書ほど速くはありませんが、かなり近いです。

import random, time
import bisect

class BisectContainsList(list):
    def __contains__(self, elem):
        i = bisect.bisect_left(self, elem)
        if i != len(self) and self[i] == elem:
            return True
        return False

test_list = [x for x in range(10000)]
test_dict = dict(zip(test_list, [True for x in range(10000)]))
test_blist = BisectContainsList(test_list)

def test(test_obj):
 s_time = time.time()
 for i in range(10000):
  random.randint(0,10000) in test_obj
 d_time = time.time() - s_time
 return d_time

print "list:", test(test_list)
print "dict:", test(test_dict)
print "blist", test(test_blist)

for (2.7でテスト済み):

list: 1.19566082954
dict: 0.0248260498047
blist 0.0598628520966
于 2012-06-04T13:42:32.743 に答える
1

リストがソートされている場合、bisectこのヘルパー関数でモジュールを使用できます。

def sorted_list_contains(alist, item):
    i = bisect.bisect_left(alist, item)
    return i != len(alist) and alist[i] == item

編集:bisectこれを投稿したときにマットアンダーソンの回答が表示されませんでした。これは代替実装として残しておきます。

于 2012-06-04T13:47:02.537 に答える