Posts python 列表推导式生成多维数组
Post
Cancel

python 列表推导式生成多维数组

列表推导式生成一维数组

列表推导式常见的 3 种形式:

  1. [x for x in data if condition] 这里的 if 主要是起到一个条件判断的作用,data 里面的数据,只有满足 if 的条件才会被留下。

  2. [exp1 if condition else exp2 for x in data] 此处if…else主要起赋值作用,当data中的数据满足if条件时将其做exp1处理,否则按照exp2处理,最后统一生成为一个数据列表。

  3. [exp1 if condition else exp2 for x in data if condition] 前面 if..else 参考第 2 种形式,后面的 if 参考 第 1 种形式。

列表推导式可以生成元素值都相等的数组。 列表推导式可以使用变量。 列表推导式可以使用 表达式。 列表推导式可以过滤一些元素。 列表推导式可以使用 if-else 做比较复杂的操作

下面的例子中 N = 4

  1. 生成nums = [0, 0, 0, 0]数组。 值都相等

    nums = [0 for i in range(N)]

相当于:

nums = []
for i in range(N):
    nums.append(0)
  1. 生成nums=[1, 2, 3, 4]数组。 使用了一个变量 i

    nums = [i for i in range(1, N+1)]

相当于:

nums = []
for i in range(1, N+1):
    nums.append(i)
  1. 生成nums=[1, 4, 9, 16] 数组 使用 i**2 表达式

    nums = [i**2 for i in range(1, N+1)]

相当于:

nums = []
for i in range(1, N+1):
    nums.append(i**2)
  1. 生成 nums=[1, 9, 25, 49]数组。 使用 if i % 2 条件判断过滤偶数,并且对奇数平方。

    nums=[i**2 for i in range(1, N*2) if i % 2]

相当于:

nums = []
for i in range(1, N*2):
    if i % 2:
        nums.append(i**2)
  1. 生成 nums=[1, -2, 3, -4] 数组。使用 if-else 将,偶数位取反。

    nums=[i if i % 2 else -i for i in range(1, N+1)]

相当于

nums = []
for i in range(1, N+1):
    if i % 2:
        nums.append(i)
    else:
        nums.append(-i)
  1. 去掉值为 3 的倍数的数,然后剩下的偶数取反。 nums=[1, -2, -4, 5, 7]

    nums=[i if i%2 else -i for i in range(1, 2*N) if i % 3]

相当于:

nums = []
for i in range(1, 2*N):
    if i % 3:
        if i % 2:
            nums.append(i)
        else:
            nums.append(-i)

以上都是一些生成一维数组的方式。

列表推导式生成多维数组

其实对于 多维数组,我感觉和 一维数组的生成方式没有什么太多的区别,就是再套一层而已。(PS: 突然想起千层饼:禁止套娃。)

  1. 生成一个 nums = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] 数组。 nums=[[j for j in range(1, N+1)] for i in range(1, N+1)]

相当于,注意下面 变量 i, j。

nums = []

for i in range(1, N+1):
    temp = []
    for j in range(1, N+1):
        temp.append(j)
    nums.append(temp)

这里我给出我写 列表推导式生成二维数组 的步骤。

  1. 我会先把 一维也就是子层嵌套的 先写出来, 假设 这一整串代码等于 A A = [j for j in range(1, N+1)]

  2. 然后 我再写 二维的 列表推导式也写出来。 [i for i in range(1, N+1)]

  3. 用 第 1 步的 那一整串代码,直接去替换 二维里面的 i。 [[j for j in range(1, N+1)] for i in range(1, N+1)]

如果这个时候我要写三维的列表推导式。 我就把前面生成二维的代码 当成一个整体 B。 B = [[j for j in range(1, N+1)] for i in range(1, N+1)]

再写 三 维的列表推导式 [k for k in range(1, N+1)]

最后把 k 替换成 B

[[[j for j in range(1, N+1)] for i in range(1, N+1)] for k in range(1, N+1)]

列表推导式的使用建议

  1. 列表推导式生成一个数组会比 使用 for 循环一个个的 append 要快。 所以对于一些简单的列表,最好是使用列表推导式。
  2. 太复杂的列表推导式,如果要照顾别人的阅读能力,考虑使用for循环嵌套。

至于对我而言,什么是比较复杂的列表推导式呢?

  1. 三维数组感觉都比较复杂。
  2. 第3种列表推导式形式。

这也不是说,复杂的列表推导式不需要学或者不应该写。前面说了,太复杂的列表推导式是因为不容易阅读,会增加沟通成本。但是如果,在一个比较复杂的列表推导式旁边再附上 多层循环的等价代码,那不管多么复杂的列表推导式,我觉得都可以接受。毕竟一串代码更多的时候是机器在运行的,那这样的话衡量代码的标准就只有时间复杂度和空间复杂度了。

阅读就是读者理解能力和作者表达能力的相遇。

This post is licensed under CC BY 4.0 by the author.
Trending Tags
Contents

Trending Tags