0

リストには、いくつかの共通要素が含まれています。

p = [('link1/d/b/c', 'target1/d/b/c'), ('link2/a/g/c', 'target2/a/g/c'), ..., ('linkn/b/b/f', 'targetn/b/b/f')]

q = [['target1/d/b/c', 'target1', 123, 334], ['targetn/b/b/f', 'targetn', 23, 64], ... ,['targetx/f/f/f', 'targetx', 999, 888]]

私はそれらを比較して共通の要素を見つけようとしており、結果でいくつかの仕事をしています:

do_job('target1/d/b/c', 'target1', 123, 334, 'link1/d/b/c')

今のところ、シンプルで非常に遅いアルゴリズムを使用しています:

for item in p:
   link = item[0]
   target = item[1]
   for item2 in q:
       target2 = item2[0]
       if target2 == target:
           do_some_job(...)

この 2 つのリストを比較して、すべての要素を含む 1 つのリストを作成する必要があると思います。

pq = [['target1/d/b/c', 'target1', 123, 334, 'link1/d/b/c'], ..., ['targetn/b/b/f', 'targetn', 23, 64, 'linkn/b/b/f']]

そして、do_some_job(pq)同じ要素が見つかったときに毎回呼び出す代わりに呼び出します

入手方法は?

よろしくお願いします

4

3 に答える 3

5

を使用chain()して 2 つのリストをフラット化し、 と を使用set()intersection()て共通の要素を取得します。

In [78]: from itertools import chain

In [79]: p
Out[79]: 
[('link1/d/b/c', 'target1/d/b/c'),
 ('link2/a/g/c', 'target2/a/g/c'),
 ('linkn/b/b/f', 'targetn/b/b/f')]

In [80]: q
Out[80]: 
[['target1/d/b/c', 'target1', 123, 334],
 ['targetn/b/b/f', 'targetn', 23, 64],
 ['targetx/f/f/f', 'targetx', 999, 888]]

In [81]: set(chain(*p)).intersection(set(chain(*q)))
Out[81]: set(['target1/d/b/c', 'targetn/b/b/f'])

またはショートサーキットでリスト内包表記を使用します:

In [86]: [j for i in p for j in i if j in (z for y in q for z in y)]
Out[86]: ['target1/d/b/c', 'targetn/b/b/f']

または使用any()

In [87]: [j for i in p for j in i if any (j==z for y in q for z in y)]
Out[87]: ['target1/d/b/c', 'targetn/b/b/f']

timeit :

In [93]: %timeit set(chain(*p)).intersection(set(chain(*q)))
100000 loops, best of 3: 7.38 us per loop                     ##  winner

In [94]: %timeit [j for i in p for j in i if j in (z for y in q for z in y)]
10000 loops, best of 3: 24.9 us per loop

In [95]: %timeit [j for i in p for j in i if any (j==z for y in q for z in y)]
10000 loops, best of 3: 27.4 us per loop

In [97]: %timeit [x for x in chain(*p) if x in chain(*q)]
10000 loops, best of 3: 12.6 us per loop
于 2012-10-23T10:20:35.413 に答える
1

おそらく辞書を使用する必要があります。

target_to_link = dict((v,k) for (k,v) in p)
for item in q:
    args = item + [target_to_link[item[0]]
    do_some_job(*args)

target_to_link辞書は、ターゲットからの対応するリンクを提供します。複数のターゲットが同じリンクを共有していないことを確認してください...

forループでは、(例: ) と対応するリンクを組み合わせた引数の一時的なリストを作成し、次の構文を使用しargsます...item['target1/d/b/c', 'target1', 123, 334]function(*args)


代わりにループする必要がある場合はp、次のような辞書を作成できます

target_to_args = dict((k[0],k[1:]) for k in q)

次に、次のようなことを行います

for (link, target) in p:
    args = [target] + target_to_args[target] + [link]
    do_some_job(*args)
于 2012-10-23T10:20:39.737 に答える
0

リスト内包表記は次のように動作するchainはずです:

[x for x in chain(*p) if x in chain(*q)]
于 2012-10-23T10:29:13.463 に答える