繁体   English   中英

递归对嵌套列表中的所有元素进行平方

[英]recursion to square all elements in nested lists

我在期中没能回答这个问题。 我不是要你们帮我做作业。 只是想知道如何解决这个问题。 我只知道如何使用列表索引来解决这个问题,但是这里不允许这个解决方案,因为问题已经说明我必须在函数中包含“for x in nums”。 我知道 int 是不可变的,那我该怎么办? 感谢“isinstance”的提示,但很抱歉我们之前没有学过,所以我不能在考试中使用它。

我刚刚学会了如何使用索引解决类似的问题。 我认为它可以像这样工作:

def square_all(nums):
    new = []
    for x in nums:
        new.append(x)
    for i in range(len(new)):
        if type(new[i]) != list:
            new[i] = new[i] ** 2
        else:
            square_all(new[i])
    return new

它不能很好地工作。 我认为“其他”有问题。 但是我该怎么修改呢?

编写一个 python 函数square_all ,它接受一个参数,一个整数嵌套列表,并返回一个新的整数嵌套列表,该列表在结构上与给定列表相同,但其中所有整数都已平方。 请注意,该函数不应修改其参数; 它应该建立一个新的、单独的列表。

通过在循环的上方、内部或下方编写您认为需要的任何内容来完成该功能。 不要在函数之外编写代码。 假设您没有可用的全局变量。 不要更改已提供的代码。

例子:

 square_all([1,2,[3,4]]) = [1,4,[9,16]]

给定代码:

 def square_all(nums;'nested list of integers') -> 'nested list of integers': for x in nums:

这是这个问题的一个非常通用的解决方案:

def map_nested(fnc, obj):
    if isinstance(l, (list, set, tuple)):  # whatever collection type you want
        return type(obj)(map_nested(fnc, sub) for sub in obj)
    return fnc(obj)        

> map_nested(lambda x: x**2, [1, 2, (3, 4, set([5, 6]))])
[1, 4, (9, 16, set([25, 36]))]

您可以将递归函数创建为:

def get_square(l):
    return [get_square(e) if isinstance(e, list) else e**2 for e in l]
    #                           ^ to check object is of `list` type

示例运行:

>>> get_square([1,2,[3,4]])
[1, 4, [9, 16]]

但是,此函数仅支持list作为嵌套对象。 如果您将元组作为嵌套结构传递,它将失败。 例如:

>>> get_square([1,2,(3,4)])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in get_square
TypeError: unsupported operand type(s) for ** or pow(): 'tuple' and 'int'

如果您希望您的函数支持所有可迭代对象,您应该对collections.Iterable进行isinstance检查。 因此你的功能应该是这样的:

from collections import Iterable

def get_square(l):
    return type(l)(get_square(e) if isinstance(e, Iterable) else e**2 for e in l)
    #        ^                        ^ check for `collections.Iterable`
    #        ^ for preserving the type of `Iterables`

示例运行:

>>> get_square([1,2,(3,4)])
[1, 4, (9, 16)]

您的代码的问题在于您创建了一个列表,因此仅调用square_all(new[i])不会更改new[i] 您必须分配结果: new[i] = square_all(new[i])

def square_all(nums):
    new = []
    for x in nums:
        new.append(x)
    for i in range(len(new)):
        if type(new[i]) != list:
            new[i] = new[i] ** 2
        else:
            new[i] = square_all(new[i])  # assign result to new[i]
    return new

或者更短一点,直接附加最终值,而不是先使用原始值,然后再覆盖它们:

def square_all(nums):
    result = []
    for n in nums:
        if type(n) is list:
            result.append(square_all(n))
        else:
            result.append(n**2)
    return result

或者非常简短,在列表理解中使用给定的代码:

def square_all(nums):
    return [square_all(n) if type(n) is list else n**2 for n in nums]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM