2013-12-18 3 views
1

2 вопросы ...питона генераторы/переменного

1) Я пытаюсь обернуть мой мозг вокруг этого ... я понять, что переменные могут принимать значения, используя такой синтаксис кода, как это:

a ,b = 2, 3 

и что это будет такой же, как кодирование:

a = 2 
b = 3 

Я надеюсь, что это правильно.

Итак, вот мое недоумение. У меня есть следующий код, используя генератор:

def fibonacci_generator() : 

    a = b = 1 

    while True : 

      yield a 

      a , b = b , a + b 


fib = fibonacci_generator() 

for i in fib : 

     if i > 100 : 

     break 

     else : 

     print ('Generated: ', i) 

print (next(fib)) 

(да это код от обучения питона книги)

Если бы я был переписать этот код и вместо того, чтобы присвоить мои а и Ь переменные следующим образом:

yield a 

a = b 

b = a + b 

затем я получаю разные возвращения для. Я не понимаю, почему это ??? Супер разочарован!

2) Когда я запускаю код, написанный в первый раз выше, я получаю номер 233, напечатанный в конце. Я также не могу понять, почему ?? !!

+0

Это, безусловно, не точный код из учебника по изучению питона. Ваш отступы отключены (я уверен, что в этом случае тот же код из этой книги);] – inspectorG4dget

+0

@aIKid Согласен. Проголосовал за закрытие. –

ответ

1
a , b = b , a + b 

не то же самое, как

a = b 
b = a + b 

Потому что, когда вы говорите

a, b = b, a + b 

Он будет первым подготовить значения на правой стороне b, a + b и назначить их переменных на оставил.

1

Python вычисляет правую часть сначала, а затем присваивает значение (или распаковывает его) с левой стороны. Так, в примере:

a, b = b, a+b 

по сравнению с:

a = b 
b = a + b 

У вас есть различные значения для a, когда вы идете, чтобы вычислить a + b. Во втором примере, когда вы вычисляете a + b, это эквивалентно вычислению b + b!

1

В задании присваивания правая сторона всегда оценивается полностью, прежде чем выполнять фактическую настройку переменных. Потому что вы получите разные результаты

0
a, b = b, a+b 

Эта строка вычисляет b и a+b перед выполнением любого задания. Строго говоря, он вычисляет кортеж (b, a+b) и затем распаковывает элементы кортежа, чтобы назначить их a и b.

a = b 
b = a+b 

Это присваивает a, затем вычисляет a+b используя новое значение a.

+2

Собственно, * строго говоря *, нет кортежа. Если вы проверите дизассемблированный код ('dis.dis'), вы заметите, что нет инструкции BUITD_TUPLE bytecode. – mgilson

+0

@mgilson: Эх, я имел в виду, что больше в терминах семантики языка, чем реализация. Это похоже на высказывание «строго говоря, вызов функции, которая возвращает int через' void (*)() 'is undefined behavior", когда действительно, конкретная комбинация используемого компилятора и параметров приводит к тому же ряду машинных команд, как если бы вы использовали 'int (*)()'. Возможно, я должен был сказать «семантически»? Трудно найти фразу, которая четко сообщает, что я говорю о том, что должен сказать код, который должен выполнять Python, а не эквивалентное действие, которое выполняет реализация. – user2357112

+0

@mgilson Его не ** всегда ** случай ... Пожалуйста, проверьте мой ответ и дискуссию с Мартиджином [здесь] (http://stackoverflow.com/a/20582989/1903116) – thefourtheye

2

В этом коде:

a, b = b, a + b 

a установлен в b и b установлен в a+b.

В этом коде:

a = b 
b = a + b 

a установлен в b и b будет впоследствии установлен a+b. Но так как a уже установлен на b, то b фактически установлен в b+b.

+1

Это самое ясное объяснение. –

+0

Geeze, Большое вам спасибо! Провел 2 дня, пытаясь просто логически сесть и выяснить, что происходит. Получил это сейчас. Ты мужчина! – user3113783

1

Возможно, вам не хватает потока данных.

a = b  ...eqI 
b = a+b ...eqII 

здесь, перед выполнением beqII, a уже хранится b как ценность сама по себе. Теперь, когда yow попробуйте выполнить b из eqII, он приходит как b=b+b. Потому что после выполнения eqI, когда дело доходит до eqII, a - b.

Но в python вы можете избежать этого конфликта, если вы попробуете a, b = b, a+b.

Для вашего второго вопроса:
Я не уверен, что ваш код, но этот один будет работать нормально в смысле кода ...

a = b = 1 
while True : 

a , b = b , a + b 

if a and b > 100: 
    break 
else: print a, b 

попробовать !!

Смежные вопросы