سؤال

ويا كل شيء، كنت أعمل على مولد عودي إلى إنشاء الأقسام صحيح ثابت من عدد وكنت في حيرة من مسألة تحديد النطاق.

ورمز يشبه هذا المقتطف.

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                yield j

ويتضح بلدي الارتباك أدناه.

>>> list(testGen([1,2],4))
yield [10, 2]
yield [10, 4]
yield [10, 7]
yield [12, 11]
yield [12, 13]
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

ويمكنني الحصول على الجواب الصحيح ببساطة عن طريق استخدام نسخة من مجموعة (يمر على سبيل المثال في a[:] لدعوة متكررة) ولكن ما زلت لا أفهم سلوك أعلاه. لماذا هي البيانات المطبوعة والقيم العائد مختلفة؟

هل كانت مفيدة؟

المحلول

ويعرض البيان الطباعة القائمة في هذه النقطة بالذات في الوقت المناسب. تغيير التعليمات البرمجية في القائمة كما يمكنك تشغيله، وذلك في الوقت الذي تدرس القائمة في النهاية، ترى قيمتها في ذلك الوقت.

ويمكنك مراقبة ذلك من خلال التنقل خلال:

>>> g = testGen([1,2],4)
>>> g.next()
('yield', [10, 2])   # note brackets in print statement because I'm on python 2.5
[10, 2]
>>> g.next()
('yield', [10, 4])
[10, 4]
>>> g.next()
('yield', [10, 7])
[10, 7]
>>> g.next()
('yield', [12, 11])
[12, 11]
>>> g.next()
('yield', [12, 13])
[12, 13]

نصائح أخرى

واعتقد ان كنت تحور مجموعة، وذلك عند طباعته له قيمة معينة، ثم في المرة التالية التي تمت طباعته تحديث فعلا قيمة، وهلم جرا. في النهاية، لديك 5 يشير إلى نفس مجموعة، وذلك بطبيعة الحال كان لديك نفس القيمة 5 مرات.

وقوائم كائنات قابلة للتغيير، إذا كنت تمر في القائمة، ومولد ينفذ عمليات في مكان على تلك القائمة، ثم أخيرا كل ما يشير إلى قائمة سيشير إلى نفس القائمة.

والقوائم المطبوعة والعائد مختلفة لأن لديك بيان طباعة واحدة فقط في حين كان لديك 2 الغلة. جرب هذا:

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                print('yield', j)
                yield j

>>> list(testGen([1,2],4))
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 7])
('yield', [10, 7])
('yield', [10, 7])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 13])
('yield', [12, 13])
('yield', [12, 13])
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

وسترى أن عائدات الماضية هي إجاباتك لأنك قد يمر حول نفس القائمة بدلا من صنع نسخة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top