首先我理解这样的写法并非最佳实践,只是想理解语言差异与背后的原因。

这是一道 LeetCode 题,讨论区里面每种语言都用了相同的解法,但只有 Python 以同样的写法陷入了死循环,问了 AI 都说两种写法等价,所以不应该存在 bug ,但实测显然是不同的,所以想问问原因。

注意看 while 循环里为两个指针连续赋值的地方。

C++ 版

ListNode *partition(ListNode *head, int x) {
    ListNode node1(0), node2(0);
    ListNode *p1 = &node1, *p2 = &node2;
    while (head) {
        if (head->val < x)
            p1 = p1->next = head;
        else
            p2 = p2->next = head;
        head = head->next;
    }
    p2->next = NULL;
    p1->next = node2.next;
    return node1.next;
}

Java 版

public ListNode partition(ListNode head, int x) {
    ListNode smallerHead = new ListNode(0), biggerHead = new ListNode(0);
    ListNode smaller = smallerHead, bigger = biggerHead;
    while (head != null) {
        if (head.val < x) {
            smaller = smaller.next = head;
        } else {
            bigger = bigger.next = head;
        }
        head = head.next;
    }
    // no need for extra check because of fake heads
    smaller.next = biggerHead.next; // join bigger after smaller
    bigger.next = null; // cut off anything after bigger
    return smallerHead.next;
}

我自己翻译的 Python 版,然而死循环导致超时:

class Solution:

    def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]:

        lt, ge = ListNode(), ListNode()
        ltPtr, gePtr = lt, ge

        while head:
            if head.val < x:
                ltPtr = ltPtr.next = head
            else:
                gePtr = gePtr.next = head

            head = head.next

        ltPtr.next, gePtr.next = ge.next, None

        return lt.next

翻了一下讨论区,下面的是没问题的 Python 版

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        head1 = tail1 = ListNode()
        head2 = tail2 = ListNode()

        while head:
            if head.val < x:
                tail1.next = tail1 = head
            else:
                tail2.next = tail2 = head
            head = head.next

        tail2.next = None
        tail1.next = head2.next
        return head1.next

问题就出在了为两个指针连续赋值的地方,所以为什么在 Python 中,p = p.next = qp.next = p = q 是不等价的呢?分别都是怎样的步骤进行赋值的?

举报· 1446 次点击
登录 注册 站外分享
13 条回复  
gydi 初学 昨天 13:06
简单用 python 测试了一下,有下面这样的结果。 >>> b = {'next': 'b'} >>> c = {'next': 'c'} >>> b = b['next'] = c >>> print(b,c) {'next': {...}} {'next': {...}} >>> b = {'next': 'b'} >>> c = {'next': 'c'} >>> b['next'] = b = c >>> print(b,c) {'next': 'c'} {'next': 'c'} 于是猜测 python 的执行对于 a=b=c 来说应该是 a=c;b=c 这样。然后搜了一下,发现这个文章 https://chowyi.com/key-points-of-chained-assignment-in-python/
rrfeng 小成 昨天 13:11
我觉得是 c 的遗留 a = ( b = c ) ( b = c )这个赋值表达式是有值的,等于 c
wang93wei 初学 昨天 13:15
https://chatgpt.com/share/676e37d2-08d0-8008-8468-45283ee66b69 这个是 O1 的解答结果……
zhouyin 小成 昨天 13:16
@rrfeng java 和 c++也是 c 系 照理说 a=b=c a 也等于 c 啊 不是吗?
wang93wei 初学 昨天 13:17
我之前写 SQL 的时候也犯过同样的问题。在 where 条件内弄了一个三个值的等式,取决于语言特性,导致 where 条件并不成立。
cmdOptionKana 初学 昨天 13:18
建议不要去搞懂 a=b=c ,同时不管哪种语言都不要使用 a=b=c ,一律拆开来写。
superhot 楼主 小成 昨天 13:24
@wang93wei 这个回答非常清晰…看来我跟 AI 对话时的描述与问题不够好
superhot 楼主 小成 昨天 13:26
@cmdOptionKana 我知道这种写法不好 只是邯郸学步 不小心踩了坑 想搞明白为啥摔了 真正工程中可不敢这么写
aijam 初学 昨天 13:33
a=b=c 在 python 里是 leftmost 所以相当于
12下一页
返回顶部