4
my_list = [1, 2]

def f():
    print my_list
    yield 11
    print my_list
    yield 22
    print my_list

my_list[:] = f()

print "finally ",
print my_list

出力:

[1, 2]
[1, 2]
[1, 2]
finally  [11, 22]

私が期待していたのは:

[1, 2]
[11, 2]
[11, 22]
finally [11, 22]

スライスの割り当てが適切に行われていると誰かが言ったことがあります。明らかにそうではありません。それを達成するエレガントな方法はありますか?

4

2 に答える 2

8

スライスの割り当てはインプレースですが、ジェネレーター全体が消費されるまで割り当ては行われません。一度に 1 つの要素をリストに割り当てるわけではありません。それらをすべて読み取り、一度にすべてをリストに貼り付けます。

(シーケンスが元のスライスとは異なる長さであっても、シーケンスをスライスに割り当てることができるため、このようにする必要があることに注意してください。たとえば、x[2:3] = [1, 2, 3, 4, 5, 6]. で1つの要素を置き換えることによってこれを行う方法はありません古いスライスとそれを置き換える新しいシーケンスとの間に 1 対 1 のマッピングがないためです。)

スライスの割り当ては常にこのように一度に機能するため、スライスの割り当てによって目的を達成する方法はありません。リストとジェネレーターを並行して繰り返し処理し、個々の要素を一度に 1 つずつ置き換える必要があります。

于 2012-08-09T05:24:23.227 に答える
2

これを行うことは可能ですが、直接ではありません。

検討:

my_list = [1,2,3,4]

def f():
    print 'first: ', my_list
    yield 11
    print 'second:', my_list
    yield 22
    print 'third: ', my_list        

def inplace(l, func):
    gen=func()
    for i,x in enumerate(l):
        try:
            l[i]=gen.next()
        except StopIteration:
            if i<len(l):
                del l[i:]
            break     

inplace(my_list,f)

print     "final: ", my_list

版画:

first:  [1, 2, 3, 4]
second: [11, 2, 3, 4]
third:  [11, 22, 3, 4]
final:  [11, 22]

もちろん、この書き方では、リストは元のリストまたはジェネレータ内の要素のどちらか短い方になります。

于 2012-08-09T20:44:31.140 に答える