将函数应用于链接列表

时间:2018-05-08 23:17:27

标签: python python-3.x

def map_link(lst, f):

"""Maps f onto each element in the linked list.

    >>> r = link(1, link(2, link(3, empty)))
    >>> map_link(r, lambda x: x**2)
    [1, [4, [9]]]
    >>> r = link(1, link(2, link(3, empty)))
    >>> map_link(r, lambda x: x + 2)
    [3, [4, [5]]]
    >>> r = link(1, link(2, link(3, empty)))
    >>> map_link(r, lambda x: -x)
    [-1, [-2, [-3]]]
    >>> r = empty
    >>> map_link(r, lambda x: -x)
    []
    """
    if lst == empty:
        return []
    else:
        return link(f(first(lst)), link(map_link(rest(lst), f), empty))

我想创建一个函数

[1, [[4, [[9, [[], 'empty']], 'empty']], 'empty']]

我的输出是这样的:

create table hierarchy (Parent varchar(3), child varchar(10))

insert into hierarchy values
('A','AB')
,('A','AC')
,('A','AD')
,('A','AE')
,('AB','ABC')
,('AB','ABD')
,('AB','ABE')
,('ABC','ABCD')
,('ABC','ABCE')
GO

; WITH cte_Hierarchy
AS
(
SELECT 
    ROW_NUMBER() OVER (ORDER BY [name]) Id
    , t.[name]
FROM(
    SELECT Parent [name] FROM hierarchy t
    UNION
    SELECT child FROM hierarchy t
)t
)
SELECT t.Id
        , t.[name]
        , h.Parent
        , p.Id ParentId
FROM cte_Hierarchy t
LEFT JOIN hierarchy h ON h.child = t.[name]
LEFT JOIN cte_Hierarchy p on p.[name] = h.Parent

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

所有这些is_linkassert根本不属于那里,这完全是&灾难性地打破了所有操作的渐近行为。

如果你删除所有不相关的assert,你会得到类似的东西:

def link(first, rest):
  return [first, rest]

def first(s):
  return s[0]

def rest(s):
  return s[1]

我不知道empty是什么,所以在下文中,我将其替换为None。 现在您可以按如下方式定义map_link

def map_link(lst, f):
  if lst is None:
    return None
  else:
    return link(f(first(lst)), map_link(rest(lst), f))

实施例。使用条目1, 2, 3

来平滑链接列表中的所有条目
print(map_link(link(1, link(2, link(3, None))), lambda x: x * x))

输出:

[1, [4, [9, None]]]

您的原始代码应该以同样的方式修复(未经测试,因为我不知道empty应该是什么):

def map_link(lst, f):
    if lst == empty:
        return empty
    else:
        return link(f(first(lst)), map_link(rest(lst), f))

答案 1 :(得分:0)

一种全新的方法是实施一个新的LinkedList课程,该课程将支持使用map

这只需要我们实施__iter__特殊方法,但这里有一个实例__len____getitem__

class LinkedList:
    Empty = object()

    def __init__(self, lst=None):
        lst = list(lst or [])
        if lst:
            self.v = lst.pop(0)
            self.tl = LinkedList(lst)
        else:
            self.v = self.Empty
            self.tl = None

    def __iter__(self):
        node = self
        while node.v is not node.Empty:
            yield node.v
            node = node.tl

    def __len__(self):
        if self.v is not self.Empty:
            return 1 + len(self.tl)
        else:
            return 0

    def __getitem__(self, item):
        if self.v is self.Empty:
            raise IndexError

        if item < 0:
            item = item % len(self)

        if item > 0:
            return self.tl[item - 1]

        return self.v

您现在可以使用map

def add_one(item):
    return item + 1

ll = LinkedList([1, 2, 3]) # [1, 2, 3]

mapped_ll = LinkedList(map(add_one, ll)) # [2, 3, 4]

然后,您可以继续实施更多特殊方法(例如__setitem__)和其他列表方法(例如insert),以使链接列表实现使用与lst相同的API。