链接列表,如果__init __()中的参数中的元素是可迭代的,则从中构造新的链接列表

时间:2015-03-27 13:35:21

标签: python python-3.x recursion linked-list initialization

我有链表的实现,

class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

class Linked_list:
    def __init__(self, llist=None):
        self.head = None
        self.tail = None
        if llist is not None:
            for i in llist:
                self.append(i)

    def add_head(self, data):
        self.head = Node(data, self.head)
        if self.tail is None:
            self.tail = self.head

    def append(self, data):
        if self.head is None:
            self.add_head(data)
        else:
            self.tail.next = Node(data)
            self.tail = self.tail.next

我想更改__init__(),所以如果llist参数包含可迭代元素(list,range(),string,tuple等),它将从中构造一个新的Linked_list。我相信递归是要走的路,但我真的很困惑如何在__init__()内实现递归。例如

a = Linked_list([1, 2, Linked_list(range(5)), Linked_list(range(3))])
b = Linked_list([1, 2, list(range(5)), list(range(3))])
c = Linked_list([1, 2,  (0, 1, 2, 3, 4), (0, 1, 2)])

a,b,c应返回相同的Linked_list

2 个答案:

答案 0 :(得分:4)

您可以使用isinstance()检查llist中值的类型并采取相应措施。递归基本上是通过构造函数免费提供的。

from collections import Iterable   # Using Python 2.7

class Linked_list:

    def __init__(self, llist=None):

        ...      # Same as your code.

        if llist is not None:
            for i in llist:
                if isinstance(i, basestring):
                    ll = Linked_list()
                    for c in i:
                        ll.append(c)
                    self.append(ll)
                elif isinstance(i, Iterable):
                    self.append(Linked_list(i))
                else:
                    self.append(i)

    ...

    def __repr__(self):
        xs = []
        nd = self.head
        while nd is not None:
            xs.append(nd.data)
            nd = nd.next
        return repr(xs)

a = Linked_list([1, 2, Linked_list(range(5)), Linked_list(range(3))])
b = Linked_list([1, 2, list(range(5)), list(range(3))])
c = Linked_list([1, 2,  (0, 1, 2, 3, 4), (0, 1, 2)])
d = Linked_list([1, 2,  (0, 1, range(4), 3, 4), (0, 1, [4,5,'abc'])])

print a
print b
print c
print d

输出:

[1, 2, [0, 1, 2, 3, 4], [0, 1, 2]]
[1, 2, [0, 1, 2, 3, 4], [0, 1, 2]]
[1, 2, [0, 1, 2, 3, 4], [0, 1, 2]]
[1, 2, [0, 1, [0, 1, 2, 3], 3, 4], [0, 1, [4, 5, ['a', 'b', 'c']]]]

答案 1 :(得分:3)

要测试某些内容是否可迭代,您可以使用collection.abc模块中的abstract base class

isinstance(llist, collection.abc.Iterable)

请注意,Python为iterable objects定义了一个行为/协议,它可能不是您练习的目的,但是您尝试遵循它可能会很有趣。