Python 中的展开列表

发布时间:2022-07-24

引言

一个列表被认为是 Python 编程语言中最灵活的数据结构之一。另一方面,通常称为列表的二维列表或 2D 列表是列表的对象,其中每个元素本身就是列表。例如: [[19, 18, 17], [16, 15, 14], [13, 12, 11]]。 展开列表是通过取消嵌套列表中保存的每个列表元素,将二维列表转换为一维列表的过程,也就是说,将 [[9, 8, 7], [6, 5, 4], [3, 2, 1]] 转换为 [9, 8, 7, 6, 5, 4, 3, 2, 1]。 我们可以借助嵌套的对循环、递归、列表推导、核心函数执行展开过程,或者在 Python 中根据嵌套列表的深度和规律性导入库或包。 在本教程中,我们将研究各种方法,以便使用 Python 编程语言来展开嵌套列表。但是在开始之前,让我们了解嵌套列表的类型。

嵌套列表有哪些类型?

我们知道,Python 是一种弱类型的编程语言。因此,我们会遇到两种类型的列表。这些列表或嵌套列表如下:

  1. 常规列表
  2. 不规则列表

常规列表

列表常规列表中的每个项目都被称为子列表,从而观察元素类型的一致性。例如: [[9, 8, 7], [6, 5, 4], [3, 2, 1]] 是常规列表,因为 [9, 8, 7][6, 5, 4][3, 2, 1] 是列表类型。

不规则列表

不规则列表中的每一项都被称为子列表或非列表元素(例如,字符串或整数)。因此,在元素类型方面存在不规则性。例如: [[9, 8, 7], [6, 5], 4, 3] 是不规则的列表,因为 [9, 8, 7][6, 5] 是列表类型,而 43int 类型。

使用嵌套循环展开列表

使用嵌套的对列表列表进行展开以获得循环的帮助被认为是获得展开列表的强力方法。我们可以通过从二维列表中选择每个项目并将其排列在一维列表中来执行此方法。 让我们考虑下面的例子,它既适用于规则列表,也适用于不规则列表。

示例:

# defining the function
def flattenlist(_2dlist):
    # defining an empty list
    flatlist = []
    # Iterating through the outer list
    for item in _2dlist:
        if type(item) is list:
            # If the item is of the list type, iterating through the sub-list
            for element in item:
                flatlist.append(element)
        else:
            flatlist.append(item)
    return flatlist
# defining the nested list
nestedlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]]
print('Genuine List:', nestedlist)
print('Converted Flat List:', flattenlist(nestedlist))

输出:

Genuine List: [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]]
Converted Flat List: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

说明:

在上面的例子中,我们定义了一个函数为 flattenlist,它接受一个参数为 _2dlist。然后,我们使用循环来迭代嵌套列表的元素,并将它们追加以生成一个扁平列表。然后,我们定义了嵌套列表并实现了 flattenlist 函数。因此,嵌套列表已成功转换为展开列表。

使用列表推导展开嵌套列表

在列表推导的帮助下展开列表被认为是一种根据二维现有列表获得展开列表的优雅方法。然而,这种方法提供了一种不太直观的解决方案。 让我们考虑下面的例子。

示例:

# defining the nested list
nestedlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
# list comprehension
flatlist = [element for sub_list in nestedlist for element in sub_list]
print('Genuine list:', nestedlist)
print('Converted list:', flatlist)

输出:

Genuine list: [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
Converted list: [10, 20, 30, 40, 50, 60, 70, 80, 90]

说明:

在上面的例子中,我们定义了嵌套列表和列表推导。然后,我们为用户打印了它们。因此,嵌套列表已成功转换为展开列表。

使用递归方法展开列表

我们也可以使用递归方法来展开二维列表。让我们考虑以下实现递归方法的示例,以便展开列表列表。这种实现适用于常规和非常规列表。

示例:

# defining a function
def flattenlist(nestedlist):
    if len(nestedlist) == 0:
        return nestedlist
    if isinstance(nestedlist[0], list):
        return flattenlist(nestedlist[0]) + flattenlist(nestedlist[1:])
    return nestedlist[:1] + flattenlist(nestedlist[1:])
print(flattenlist([[10, 20, 30, 40], [50, 60, 70], [80, 90], 100]))

输出:

[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

说明:

在上面的例子中,我们定义了一个函数,并使用了 if 语句来声明嵌套列表的长度是否等于零,然后返回嵌套列表。 如果第零个索引上的数据元素是列表的一个实例,那么列表索引将再次进入函数,并添加到列表的下一个索引中,以此类推。否则函数将返回元素等等。最后,我们定义了嵌套列表并执行了函数。结果,列表列表递归地变平了。

利用 Python 库

我们还可以利用一些 Python 编程语言库来展开列表。这些库的实现描述如下:

使用功能工具和操作员库展开列表列表

运算符库提供了 iconcat() 函数来执行基本操作,如连接。我们可以将此函数从左到右累积应用于嵌套列表的数据元素,从而将嵌套列表简化为扁平列表。 让我们考虑下面的例子来理解它的实现。

示例:

# importing the required libraries
import operator
import functools
regularlist = []
# Converting the list of lists into a flattened one.
def convo(nestedlist):
    for element in nestedlist:
        if type(element) is list:
            regularlist.append(element)
        else:
            regularlist.append([element])
    return regularlist
twoDlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100], 110]
regular2Dlist = convo(twoDlist)
print('Given List:', twoDlist)
print('Converted list:', functools.reduce(operator.iconcat, regular2Dlist, []))

输出:

Given List: [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100], 110]
Converted list: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110]

说明:

在上面的例子中,我们已经导入了功能工具库和操作符库。然后,我们将一个空列表定义为常规列表。然后,我们定义了一个函数 convolution 来将列表转换为扁平列表。在这个函数中,我们将用于循环,其中嵌套列表中的元素被追加到我们之前定义的空列表中。稍后,我们已经定义了嵌套列表并执行了函数。因此,列表列表被成功转换为展开列表。

使用 itertools 库展开列表列表

itertools 库提供了 chain() 功能,允许我们理想地将嵌套列表转换为单个扁平列表。该函数通过以串行方式通过作为参数传递的 iterable 对连续序列进行迭代,将它们视为单个序列。 让我们考虑下面的例子:

示例:

# importing the itertools library
import itertools
# defining the nested list
nestedlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]]
flattenlist = list(itertools.chain(*nestedlist))
print('The nested list:', nestedlist)
print('The flattened list:', flattenlist)

输出:

The nested list: [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]]
The flattened list: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

说明:

在上面的例子中,我们已经导入了 itertools 库并生成了一个嵌套列表。然后,我们使用 chain() 函数将给定的嵌套列表转换为扁平列表。最后,我们将结果返回给用户。结果,列表列表被成功展开。

使用 NumPy 库展开列表列表

NumPy 库提供各种日常操作,包括按列或按行连接二维常规数组。我们将使用称为 flat 的属性,以便在数组上获得一维迭代器来征服目标。让我们考虑下面的例子来理解 concatenate 函数和 flat 属性的使用。

示例:

# importing the library
import numpy
# defining the nested list
nestedlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
# using the concatenate function along with the flat attribute
flattenlist = list(numpy.concatenate(nestedlist).flat)
print('The Nested list:', nestedlist)
print('The Flattened list:', flattenlist)

输出:

The Nested list: [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
The Flattened list: [10, 20, 30, 40, 50, 60, 70, 80, 90]

说明:

在上面的例子中,我们已经导入了 numpy 库并定义了一个嵌套列表。然后,我们使用了 numpy 库的 concatenate 函数及其 flat 属性来展开嵌套列表的元素,并将它们连接到一个新的扁平列表。最后,我们为用户打印了结果。因此,列表列表被成功展开。

利用核心功能

我们还可以利用 Python 编程语言提供的一些核心功能来执行展开任务。

使用求和功能展开列表列表

我们可以考虑对内部列表求和,作为解决问题的另一种方法。我们将两个参数传递给 sum 函数:第一个参数是可迭代,这是一个嵌套列表,第二个参数是 start,这是一个空列表,用于以下情况,作为内部子列表的数据元素将添加到的初始平面列表。 我们可以说这种方法非常方便,因为我们不需要导入任何东西。但是,当嵌套列表中存在大量子列表时,它比 itertools()chain() 函数慢。

示例:

# defining a nested list
nestedlist = [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
# using the sum function
flattenlist = sum(nestedlist, [])
print('The Nested list:', nestedlist)
print('The Flattened list:', flattenlist)

输出:

The Nested list: [[10, 20, 30, 40], [50, 60, 70], [80, 90]]
The Flattened list: [10, 20, 30, 40, 50, 60, 70, 80, 90]

说明:

在上面的例子中,我们已经定义了嵌套列表。然后,我们使用 sum() 函数,将嵌套列表展开为一维列表,并为用户打印结果列表。结果,我们成功地将列表列表转换为平面列表。

使用 Lambda 关键字展开列表列表

我们可以使用关键字 lambda 定义一个匿名函数。我们可以将规则/不规则列表作为参数传递给这个匿名函数。表达式的计算是为了得到一个平面的一维列表。 让我们考虑下面的例子:

示例:

# Defining the nested list
nestedlist = [[10, 20, 30], [30, 50, 60], [40, 60, 70], 70]
# Using lambda parameters: expression
flattenlist = lambda nestedlist:[item for element in nestedlist for item in flattenlist(element)] if type(nestedlist) is list else [nestedlist]
print("The Nested list:", nestedlist)
print("The Flattened List:", flattenlist(nestedlist))

输出:

The Nested list: [[10, 20, 30], [30, 50, 60], [40, 60, 70], 70]
The Flattened List: [10, 20, 30, 30, 50, 60, 40, 60, 70, 70]

说明:

在上面的例子中,我们定义了一个嵌套列表。然后,我们使用了 lambda 关键字以及定义列表推导表达式的参数。然后,我们为用户打印了它们。因此,我们成功地将二维不规则列表转换为扁平列表。