обмен значениями Python с использованием запятой вызывает путаницу - PullRequest
3 голосов
/ 25 апреля 2019

это связано с проблемой, с которой я столкнулся, пытаясь решить обратную проблему связанного списка.

Сначала позвольте мне добавить некоторые предварительные коды для определения связанного списка и быстрый метод создания связанного списка:

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

    def __repr__(self):
        if self.next:
            return "{}->{}".format(self.val, repr(self.next))
        else:
            return "{}".format(self.val)

def genNode(*nodes, end=None):
    if len(nodes) == 1 and type(nodes[0]) == list:
        nodes = nodes[0]
    for i in nodes[::-1]:
        n = ListNode(i)
        n.next, end = end, n
    return n if nodes else None

Проблема, с которой я столкнулся, заключается в том, что я обнаружил, что механизм подкачки все еще зависит от последовательности переменной, которую я пишу.

Первоначально, когда мы говорим о подстановке значений в python, мы можемdo:

a, b = b, a

и он должен работать точно так же, если у меня есть

b, a = a, b

Этот метод обратного связанного списка, который я пытаюсь написать, имеет перестановку 3 переменных, идея проста, чтобы создать фиктивную головку и последовательно добавлять узлы между dummy и dummy.next, чтобы ее можно было перевернуть.

def rev(head):
    dummy = ListNode('X')
    while head:
        dummy.next, head.next, head = head, dummy.next, head.next
    return dummy.next

a = genNode(1,2,3,4)
print(rev(a)) # >>> 4->3->2->1

Но если я слегка переключу последовательность из 3 переменных:

def rev2(head):
    dummy = ListNode('X')
    while head:
        dummy.next, head, head.next, = head, head.next, dummy.next,
    return dummy.next

a = genNode(1,2,3,4)
print(rev2(a))  # >>> AttributeError: 'NoneType' object has no attribute 'next'

Так что похоже, что здесь имеет значение последовательность, и может кто-нибудь дать мне знать, как python оценивает значения подкачки, если существует более 2 переменных.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 25 апреля 2019

слева направо

Посмотрите на https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

Детали реализации CPython: в текущей реализации синтаксис для целей принимается таким же, как для выражений, а недопустимый синтаксис отклоняется на этапе генерации кода, вызывая менее подробные сообщения об ошибках.

Хотя определение присваивания подразумевает, что перекрытия между левой и правой сторонами являются «одновременными» (например, a, b = b, перестановка двух переменных), перекрытия в наборе назначенных для переменные встречаются слева направо, что иногда приводит к путанице. Например, следующая программа печатает [0, 2]:

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i is updated, then x[i] is updated
print(x)
1 голос
/ 25 апреля 2019

Простой пример, приведенный ниже, должен показать вам предостережение об использовании подкачки для класса, подобного ListNode

. Давайте определим список из 3 элементов.

a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
a.next = b
b.next = c
print(a)
#1->2->3

Теперь, если мы поменяем, скажем,b и c, это не будет иметь никакого эффекта

b,c = c,b
print(a)
#1->2->3

Если мы поменяем местами a и b, связанный список изменится.

a,b=b,a
print(a)
#2->3

Аналогично для свопов a и c.

a,c=c,a
print(a)
#3

Таким образом, вы можете видеть, что использование простой логики свопинга несовместимо с тем, как она применяется к ListNode, поэтому следует избегать.

0 голосов
/ 25 апреля 2019

Если существует более двух переменных, он работает так же, как и с двумя.Вы помещаете их в желаемый конечный порядок:

>>> a = 1
>>> b = 2
>>> c = 3
>>> c,b,a = a,b,c
>>> a,b,c
(3, 2, 1)
...