【问题标题】:Creating a list of integers from a nested list?从嵌套列表中创建整数列表?
【发布时间】:2012-11-23 03:32:15
【问题描述】:

我有一个嵌套列表,例如:

 test = [[15, [7, [None], [11, [None], [13, [None], [None]]]], [None]], [20, [None], [None]]] 

我想从中创建另一个列表,其中仅包含嵌套中的整数。哪个会返回这个:

[15, 7, 11, 13, 20]

我已经创建了这个递归函数来完成我需要完成的事情,但是,我不禁认为这不是最好的方法。有没有更pythonic或更有效的方法来做到这一点?

def nest_search(nest, hold=[]):
    for item in nest:
        if isinstance(item, int):
            hold.append(item)
        if isinstance(item, list):
            nest_search(item, hold)
    return hold

>>> print nest_search(test)
[15, 7, 11, 13, 20]

【问题讨论】:

  • 你要找的操作叫做flatten。在 python 中搜索扁平化列表。
  • Flatten 然后过滤
  • 我以前扁平化过列表,我认为这不适用于我发布的示例list
  • 它应该......但是你很接近我修改了你的功能,现在它应该可以工作了
  • 我见过的所有“干净”(单线/pythonic)扁平化算法都只适用于列表列表,而不适用于任意深度的列表。

标签: python nested-lists


【解决方案1】:

我看到的唯一不符合 Python 的就是默认参数。请参阅 this question 了解为什么这不会按您的预期方式工作。

这是我的解决方法:

def nest_search(nest, hold=None):
    if hold is None:
        hold = []
    for item in nest:
        if isinstance(item, int):
            hold.append(item)
        if isinstance(item, list):
            nest_search(item, hold)
    return hold

另一种实现方式是使函数成为生成器,它一个一个地产生值,而不是将它们添加到它最后返回的列表中。 (如果您确实需要一个列表,只需将生成器调用包装在 list 构造函数中即可。

def nest_search_gen(nest):
    for item in nest:
        if isinstance(item, int):
            yield item
        if isinstance(item, list):
            yield from nest_search_gen(item)

这使用了 Python 3.3 中引入的新 yield from 语法。如果您使用的是早期版本,您可以通过将最后一行替换为:

for i in nest_search_gen(item):
    yield i

【讨论】:

  • 我喜欢使用生成器的想法,我会用默认参数来检查我的错误。
【解决方案2】:

使用flatten 发布的here 解决方案,您可以尝试以下方法。

>>> def flatten(x):
    try:
      it = iter(x)
    except TypeError:
      yield x
    else:
      for i in it:
        for j in flatten(i):
          yield j
>>> filter(bool, flatten(test))
[15, 7, 11, 13, 20]

我认为 flattenfilter 两个独立函数的使用更清晰,并且您鼓励模块化,允许一个单独使用另一个。

【讨论】:

  • 这个flatten 解决方案与@Blckknght 通过调整我发布到生成器的递归函数所建议的非常相似,但是try/except 的使用通常被视为比@ 更好的选择987654328@对吗?
  • 这是 LBYLEAFP 的情况,两者都可以接受。
  • 这个flatten 代码的唯一问题,以及LBYL 可能更适合这个特定问题的一个原因是字符串看起来像无限嵌套的序列。也就是说,它们是可迭代的,并且它们的所有成员项也是可迭代的,因为它们是(一个字符)字符串。试试:flatten(["AB", ["C"]]),它会在“A”上一直递归到递归限制。
猜你喜欢
  • 1970-01-01
  • 2014-02-02
  • 2022-01-19
  • 1970-01-01
  • 2020-10-22
  • 2021-09-15
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多