【问题标题】:Count lists inside a list recursively [closed]递归地计算列表中的列表[关闭]
【发布时间】:2021-08-31 11:31:07
【问题描述】:

假设我们有不同数量的子列表,并且想要递归地计算子列表

Example 1: l1 = [['a', 'bb'], ['c', 'a']] => count two sublists
Example 2: l2 = [[['c', 'x'], ['g', 'ad']], [['a', 'bb'], ['c', 'a']]] => count six sublists

关于这个主题已经有几个线程:non recursive 或for elements in a function。我仍然想知道是否有比调用递归函数并每次检查元素是否为列表更 Pythonic 的解决方案。

感谢您的任何想法

【问题讨论】:

  • 你可以使用len() 对吗?还是你想要另一种方式?
  • @PCM len(l2) 是 2 对吗?
  • @KlausD。请告诉我我的问题在哪里重复?你能苹果引用我的例子并得到正确答案吗?
  • 您自己链接了副本。他们对问题有有效的解决方案。只是你不满意他们不够“pythonic”,这是一个非常主观的术语。你必须提出一个可靠的标准,并解释为什么你需要这个标准而不是个人喜好。

标签: python list recursion count


【解决方案1】:

您可以尝试以下方式:

def rec_len(obj):
    return sum(1 + rec_len(e) for e in obj if isinstance(e, list))

rec_len([[['c', 'x'], ['g', 'ad']], [['a', 'bb'], ['c', 'a']]])
# 6

或非递归,使用堆栈:

def iter_len(obj):
    total, agenda = 0, obj[:]
    while agenda:
        x = agenda.pop()
        if isinstance(x, list):
            total += 1
            agenda.extend(x)
    return total

如果只是为了将列表与其他可迭代对象(如字符串)区分开来,您将不得不进行某种类型的检查。

【讨论】:

  • 感谢您提供递归和迭代解决方案
【解决方案2】:

由于您只对子列表的数量感兴趣,您可以这样做:

print(str(l2).count('[')-1)

# 6

速度:

每个循环 2.04 µs ± 139 ns(平均值 ± 标准偏差,7 次运行,每次 100000 次循环)

*假设这些括号不是子列表值的一部分

【讨论】:

  • 其实这个安静的不错,不知道为什么有人不喜欢它!
  • @JürgenK。谢谢,我也很困惑。当然,在子列表中没有[ 是有限制的,否则逻辑会被搞砸,但如果这是给定的,我认为速度和可读性相当好。希望这会有所帮助!
  • 我认为这不应该被推荐为一种有效的方法。它规避了算法挑战(将其传递给str 并为初学者提供很少的洞察力)并取决于实际数据的优雅。
  • @schwobaseggl,我认为您有三个有效点,但 OP 已经引用了“最佳实践”方法。 (i) 因此,初学者可以很容易地找到“更清洁”的替代品。 (ii) 算法挑战被跳过了,是的,因为它已经在其他不同的 SO 问题中得到解决。 (iii) 因此,数据依赖是最关键的批评点,你是绝对正确的。我认为这是一个利基解决方案,但在我看来,这是 OP 所要求的。
【解决方案3】:

以下是列表计数问题的递归解决方案:

def list_counter(list_, count=0):
    for x in list_:
        if isinstance(x, list):
            count += 1
            count = list_counter(x, count=count)
    return count

例子:

l1 = [['a', 'bb'], ['c', 'a']]
l2 = [[['c', 'x'], ['g', 'ad']], [['a', 'bb'], ['c', 'a']]]
print(list_counter(l1))
print(list_counter(l2))

>>> 2
>>> 6

【讨论】:

  • 谢谢。我在我的问题中描述了这样的解决方案,并想知道是否还有其他方法。
  • 您为什么选择将count 设为可选参数而不是内部变量?我认为它作为区间变量不会那么混乱,在开头添加count = 0,并将count += 1; count = list_counter(x, count=count)替换为count += 1 + list_counter(x)
  • 你也可以用return sum(1 + list_counter(x) for x in list_ if isinstance(x,list))替换整个list_counter
  • 由于 schwobaseggl 和 Andreas 提供了最佳答案,我想分享一个初学者友好的语法,以帮助更好地理解这个递归函数。但是,如果它被判断为无用,我不介意删除我的答案
【解决方案4】:

试试这个(没有循环的纯递归方法):

def counter(lst, index, count):
    
    if lst[index] == ']' and index == len(lst)-1:
        print(count-1)
    
    else:
        if lst[index] == '[':
            count += 1
        index += 1
        counter(lst, index, count)

司机:

nested_list = [[['c', 'x'], ['g', 'ad']], [['a', 'bb'], ['c', 'a']]]
counter(str(nested_list), index=0, count=0)

输出:

6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多