如何以递归方式修改深层嵌套列表的每个值并返回另一个类似的列表?

时间:2015-10-15 18:17:44

标签: python list recursion nested

我想采用嵌套列表

[[[2,3],[5,6]], 2, [2,4,5],[3,4,5]]

以递归方式进入,修改每个值,然后返回类似的列表。例如,假设我想为每个值添加1,输出将是

def add1(nodelist):
    list_of_lists = []
    name_nodes.nodes = []
    def recurse_list(nodelist):
        name_nodes.nodes = []
        edit_list = False
        for r in nodelist:
            if type(r) == list:
                recurse_list(r)
            else:
                edit_list = True
                name_nodes.nodes.append(r+1)
        if edit_list == True:
            list_of_lists.append(name_nodes.nodes)
    recurse_list(nodelist)
    return list_of_lists

通过制作递归函数,我已经取得了一些进展,我测试它是否是要修改的列表或元素。在谈到如何再次编译列表时,我感到很难过。难道没有一种简单的方法可以做到这一点吗?以下代码是我目前所拥有的。

[[2, 3], [5, 6, 2], [2, 4, 5], [3, 4, 5], [3, 4, 5]]

此代码获取以下输出

class Link(models.Model):
    title       = models.CharField(max_length=200)
    . . . 

class Vote(models.Model):
    UP, DOWN = range(2)
    TYPE_CHOICES = [(UP, "Upvote"), (DOWN, "DownVote")]

    link = models.ForeignKey(Link, related_name='votes')
    vote_type = models.IntegerField(choices=TYPE_CHOICES, db_index=True)
    . . . 

我很惊讶那里没有一些模块或一些内置功能来更好地处理嵌套列表,因为有很多问题处理相似但不同的行为。我能找到的最接近的问题是here。但那并不完全正是我所寻找的。谢谢你的回答。

2 个答案:

答案 0 :(得分:3)

def add1(L):
    for i, elem in enumerate(L):
        if isinstance(elem, int):
            L[i] += 1
        else:
            L[i] = add1(elem)
    return L

输出:

>>> L = [[[1,2],[4,5]], 1, [1,3,4],[2,3,4]]
>>> add1(L)
[[[2, 3], [5, 6]], 2, [2, 4, 5], [3, 4, 5]]

答案 1 :(得分:0)

实际上,我最近一直在考虑这个问题。这是我为此编写的代码的一部分,摘录自一些演示。函数nmap()的工作方式与map()内置函数类似,但它适用于嵌套列表。

import functools


def mapper_nester(function):
    @functools.wraps(function)
    def wrapper(*point):
        try:
            res = function(*point)
        except TypeError:
            res = map(mapper_nester(function), *point)
        return res
    return wrapper


def nmap(function, *seq):
    """nmap(funtion, seq[, seq ...]) -> nested list of similar structure."""
    return map(mapper_nester(function), *seq)

>>> nested_list = [0, [1], [[[[2]]]],
                   [3, [], [4, 5]],
                   [6, [7, 8],
                    9, [[[]], 10, []]], 11,
                   [], [], [12]]
>>> nmap(lambda x: x + 1, nested_list)
[1,
 [2],
 [[[[3]]]],
 [4, [], [5, 6]],
 [7, [8, 9], 10, [[[]], 11, []]],
 12,
 [],
 [],
 [13]]

这是一个遍历嵌套(递归)结构的递归函数。

优点:

缺点:

  • 它受到递归限制,因此对深层嵌套列表不太有用。
  • 在Python上下文中,递归函数通常是不受欢迎的。
  • 此函数使用TypeError来检查节点的“类型”(原子或原子集合),但这并不总是可靠的(并且取决于映射函数实际执行的操作),尤其是Python duck typing。

实际上我已经编写了很多代码来解决最后一个问题,但是在这里投入很麻烦。[1]

[1]它的作用是创建一个临时的,有限的“类型宇宙”,它可以清楚地区分原子与原子集合(这是以丑陋的方式完成的,使用isinstance()和朋友,以及创建这个“类型化的宇宙”可以自定义),然后将数据和待映射函数提升到这个宇宙中,其中提升函数只能作用于原子并产生原子作为值。嵌套映射在此Universe中完成,然后可选择将结果降级为通常的Python Universe。