1

次のコードをリファクタリングする方法があるかどうか疑問に思いました

 first_run = True
 for i in gen:
        if first_run:
            last_head = i[1]
            last_tail = i[2]
            last_chrom = i[0]
            first_run = False
        else:
            func(i[1], last_head)
            func(i[1], last_tail)
            last_head = i[1]
            last_tail = i[2]
            last_chrom = i[0]
4

6 に答える 6

5

ループの重要なポイントは、反復可能要素の連続する要素のペアに対して何らかの操作を実行することのようです。したがって、モジュールのドキュメントpairwiseに定義が記載されている関数を調べます。itertools

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

これは実際のitertools関数ではないことに注意してください。実装をコピーしてコードに貼り付ける必要があります。とにかく、この関数を使用すると、ループを次のように実装できます。

for a, b in pairwise(gen):
    func(b[1], a[1])
    func(b[1], a[2])
于 2012-10-30T08:33:12.697 に答える
1

if / elseを削除し、リストをスライスして割り当てます-funcの引数がそれによって更新されるオブジェクトでない限り:genがジェネレーターの場合:

my_gen = gen
values = my_gen.next()
last_chrom, last_head, last_tail = values[:3]
for values in my_gen:
    func(last_head, last_head)
    func(last_head, last_tail)
    last_chrom, last_head, last_tail = values[:3]

編集:ちょうど私の間違いに気づいた

于 2012-10-30T07:57:14.950 に答える
1

これにより、ループが単純化されます

first_run = True
for i in gen:
    if first_run == False:
        func(i[1], last_head)
        func(i[1], last_tail)

     last_head, last_tail, last_chrom  = i[1], i[2], i[0]
     first_run = False

答えを更新しました...

于 2012-10-30T07:48:13.423 に答える
0

ループの後に変数last_head、last_tail、last_chromが必要ない場合は、次の解決策をとることができます。

for index, val in enumerate(gen[:1]):
    func(val[1], gen[index-1][1])
    func(val[1], gen[index-1][2])
于 2012-10-30T07:57:23.010 に答える
0
it = iter(gen) # make sure we have an iterator
_, last_head, last_tail = next(it, [None]*3) # assume iterator returns 3 values
for _, head, tail in it:
    func(head, last_head)
    func(head, last_tail)
    last_head, last_tail = head, tail

イテレータが一度に3つの値を返すと想定できない場合は、次のようにします。

it = iter(gen)
last = next(it, None)
for x in it:
    func(x[1], last[1]) # head, last_head
    func(x[1], last[2]) # head, last_tail
    last = x

@Davidによって提案されたitertools'pairwise()レシピを使用することもできます:

for last, x in pairwise(gen):
    func(x[1], last[1]) # head, last_head
    func(x[1], last[2]) # head, last_tail
于 2012-10-30T08:46:16.217 に答える
0

「最初のアイテム」を特別な方法で処理する私のお気に入りの方法は、次のような1回限りのループbreakです。

def gen():
    for x in range(5):
        yield x

def first_special(g):
    for item in g:
        print 'first', item
        break
    for item in g:
        print item

 first_special(gen())
 # prints "first 0, 1,2,3,4

これは、1要素または空のイテレータで正常に機能することに注意してください。任意の反復可能オブジェクトでも機能させるためfirst_specialに、私は通常、それに安全iter()呼び出しを追加します。

def first_special(g):
    g = iter(g)
    for item in g:
        print 'first', item
        break
    for item in g:
        print item
于 2012-10-30T09:43:24.173 に答える