54957


Linked ListをPython3実装し、トラバーサルの実装方法で質問です  
下記のような前提条件があったとします。

### 前提条件

[code]

    Linked Listのノードクラス
    class Node:
        def __init__(self, x):
            self.val = x
            self.next = None
    
    # 初期化
    node = Node(1)
    node.next = Node(2)
    node.next.next = Node(3)
    
    
[/code]

### 質問

ノードをたどっていく下記の二方法の実装ではどのような違いがありますか？

方法1

[code]

    while node:
        node = node.next
    
[/code]

方法2

[code]

    while node is not None:
        node = node.next
    
[/code]

### 補足

nodeがNoneでないことを素直に実装すると方法2になると思います。  
ですが、LeetCodeやAOJ, AtCoderなどで他の人が実装したLinked Listを見ると、  
たいてい方法1で実装しています。もし方法1でも方法2と同じ挙動なら方法1のほうが短くていいなと思っています。


CC BY-SA 4.0
2019-05-14T11:43:01.863
54948
2019-05-15T01:15:33.930
32428
question
python python3 データ構造
Linked Listのトラバーサルの方法で質問です


方法1と方法2には違いがあります。  
その違いを端的に示すコードは下記です。  
初期化時に`node.next.next = False`としている点に注目してください。

[code]

    # Linked Listのノードクラス
    class Node:
        def __init__(self, x):
            self.val = x
            self.next = None
    
    # 初期化(使いまわしのために関数化)
    def get_node():
        node = Node(1)
        node.next = Node(2)
        ### 型安全ではないので、何でも入ります！
        node.next.next = False
        return node
    
    node = get_node()
    # 方法1(エラーにならない)
    while node:
        print(node.val)
        node = node.next
    
    # 1
    # 2
    
    node = get_node()
    # 方法2(エラーになる)
    while node is not None:
        print(node.val)
        node = node.next
    
    # 1
    # 2
    # Traceback (most recent call last):
    #   File "<stdin>", line 3, in <module>
    # AttributeError: 'bool' object has no attribute 'val'
    
[/code]

たいていの開発者が`LinkedList.next`に`False`や`0`を入れないので、クラスのチェック処理や変数のスコープが正しければ方法1の実装で問題ないと思います。

しかし本家SOの [類似](https://stackoverflow.com/a/7816439)
[回答](https://stackoverflow.com/a/3901191) などを参考にして違いを把握することをお勧めします。

python3では、`if a:`と`if
a.__bool__()`が[等価](https://docs.python.org/3/reference/datamodel.html#object.__bool__)であり、`if
a is not None:`は単純に`a`と`None`が同じか比較するだけの挙動となります。

[code]

    tests = [False , "", 0, 0.0, [], (), {}, set()]
    for test in tests:
        if test:
            # すべて通過しない
            print("if {}: True".format(test))
        if test is not None:
            # すべて通過する
            print("if {} is not None: True".format(test))
    
[/code]


CC BY-SA 4.0
2019-05-15T01:15:33.930
54957
2019-05-15T01:15:33.930
9820
54948
answer