【问题标题】:Is this an application for a genuine linked list in python?这是python中真正链表的应用程序吗?
【发布时间】:2018-01-22 02:55:36
【问题描述】:

我有一长串按顺序遍历的状态。 遍历状态意味着生成一个新状态,作为现有状态的替代。 经过少量的遍历,我得出要么成功要么失败的结论。 如果成功,那么我的新列表是列表顶部的已修改状态,并且所有未遍历的元素均未更改。 如果我得出失败的结论,我只返回原始列表。也就是说,我通过丢弃更改来“撤消”。

可以通过将我的新状态列表与原始列表的一部分连接起来来完成成功案例。但是,如果我理解正确,切片会做浅拷贝。对于一长串清单来说,这似乎是不必要的成本。如果我有一个链表,我想我可以以非常低的成本做到这一点。

我应该在 python 中将其实现为链表吗? [因为如果列表需要修改,列表头部的元素可以简单地通过更改指针添加到未修改的尾部,无需 O(N) 复制列表,这是 Python 列表无法避免的]

编辑 迭代器似乎是一个很好的 Python 解决方案。请看下面我的回答。 显然,这个要求是'retroactive data structure'

【问题讨论】:

  • 一个普通的列表可以吗?
  • 列表切片不是“浅拷贝”
  • @donkopotamus,哦,我还以为是:stackoverflow.com/a/19068714/4834
  • @quamrana 列表切片可能是列表的“浅拷贝”,但其中的项目不是原始列表中项目的“浅拷贝”,这似乎是 OP 的担心(否则他们没有理由认为创建一个新的链表会更便宜)
  • 哦,我认为 OP 关心的是生成切片,例如。 oldlist[n:] 其中len(oldlist) >> n 会很贵。

标签: python list data-structures


【解决方案1】:

如果您希望只遍历几个项目,那么您可以在知道结果后将新项目覆盖到旧列表中。

def traverse_states(states):
    new_list = []
    for state in states:
        new_state, result = traverse(state) # result is in [None, True, False]
        new_list.append(new_state)
        if result is not None:
            if result == True:
                for index, new_state in enumerate(new_list):
                    states[index] = new_state
            return

用法:

some_states = create_states() # returns list of states

traverse_states(some_states)

some_states 是原始列表或替换了前几项的相同列表。

【讨论】:

  • 我知道我可以做到这一点:) 但它很丑;这意味着重申。最高出价者仍然是一个链表...
  • 您可以轻松地为链表编写代码,并且在返回链表(新的或旧的)时,您将获得所需的性能。使用非内置类型的“列表”时,您还必须考虑代码维护成本。
  • 当您阅读有关此主题的堆栈溢出时,很容易发现在少数情况下链接列表会比列表更好的选择。但毕竟找到一个例子似乎并不难。
  • 但不知何故我想知道是否有一个迭代器解决方案,将新头的迭代器与原始列表的剩余迭代器链接起来
  • 顺便说一句,ChainMap 数据结构也很有帮助:它似乎是一种在不更改原始 dict 的情况下对 dict 进行分层更改的快速方法。
【解决方案2】:

假设 iter() 的成本很便宜,我认为这段代码在 python 中显示了一个很好的解决方案。

import itertools
from random import randint

original_iterator = range(0, 99)
processing_iterator = iter(original_iterator)
outcome = 'Failure'

l2 = []
for i in processing_iterator:
    l2.append('a')  # change the state
    random_event = randint(0, 9)
    if random_event == 1:  # success
        result_list = itertools.chain(l2, processing_iterator)
        outcome = 'Success'
        break
    elif random_event == 2:  # failure
        result_list = original_iterator
        break
else:  # failure by exhaustion
    result_list = original_iterator  

print("Result", outcome, (list(result_list)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 2012-12-15
    • 2012-11-25
    • 1970-01-01
    • 2015-06-02
    • 2021-09-12
    • 2018-05-09
    • 1970-01-01
    相关资源
    最近更新 更多