37 列表推导式

列表推导式(list comprehension) 也成为列表解析式,可以使用非常简洁的方式对列表或其他可迭代对象的元素进行遍历、过滤或再次计算,快速生成满足特定需求的新列表,代码非常简洁,具有很强的可读性,是 python 程序开发过程时应用最多的技术之一。Python 的内部实现对列表推导式做了大量语法优化,可以保证很快的运行速度,也是推荐使用的一种技术。
列表推导式在逻辑上等价于一个循环语句,只是在形式上更加简洁。

x = [x * x for x in range(10)]
print(x)
# 等价于
x = []
for i in range(10):
    x.append(i * i)
print(x)

y = ['banana', 'loganberry', 'passion fruit']
print([i.strip() for i in y])
# 等价于
z = []
for i in y:
    z.append(i.strip())
print(z)
# 等价于
print(list(map(lambda i: i.strip(), y)))
print(list(map(str.strip, y)))

在这里插入图片描述

1 实现嵌套列表的平铺

列表推导式中有两个循环,第一个循环可以看作外循环,执行得慢;第二个循环可以看作内循环,执行得快。

from itertools import chain

vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([j for i in vec for j in i])
# 等价于
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
s = []
for i in vec:
    for j in i:
        s.append(j)
print(s)
print(list(chain(*vec)))

在这里插入图片描述

如果有多级嵌套或者不同子列表嵌套深度不同,就不能使用上面的方法了。这时,可以使用函数递归实现。

def flat_list(s):
    g = []  # 存放最终结果的列表

    def nested(s):  # 函数嵌套定义
        for i in s:
            if isinstance(i, list):
                nested(i)  # 递归子列表
            else:
                g.append(i)  # 扁平化列表

    nested(s)  # 调用嵌套定义的函数
    return g  # 返回结果


vec = [[1], [1, 'g'], ['a'], [], [12, 24]]
print(flat_list(vec))

在这里插入图片描述

2 过滤不符合条件的语句

在列表推导式中可以使用 if 子句对列表中的元素进行筛选,只在结果列表中保留符合条件的元素。

vec = [-1, -4.6, 7.5, -2.3, 9, -11]
print([i for i in vec if i > 0])  # 所有大于 0 的数字

scores = {'zs': 45, 'ls': 78, 'ww': 40, 'zl': 96,
          'zq': 65, 'sb': 90, 'zj': 78, 'ws': 99, 'ds': 60}
highest = max(scores.values())  # 最高分
lowest = min(scores.values())  # 最低分
avg = sum(scores.values()) / len(scores)  # 平均分
print(highest, lowest, avg)
highest_person = [name for name, score in scores.items() if score == highest]
print(highest_person)

在这里插入图片描述

from random import randint

# 使用列表推导式查找列表中最大元素的所有位置
x = [randint(10, 100) for i in range(10)]  # 10个介于[10,100]之间的整数
print(x)
print([index for index, value in enumerate(x) if value == max(x)])

在这里插入图片描述

3 同时遍历多个列表或可迭代对象

对于包含多个循环的列表推导式,一定要清楚多个循环的执行顺序或 “嵌套关系”。

print([(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y])
# 等价于
g = []
for x in [1, 2, 3]:
    for y in [3, 1, 4]:
        if x != y:
            g.append((x, y))
print(g)

print([(x, y) for x in [1, 2, 3] if x == 1 for y in [3, 1, 4] if x != y])

在这里插入图片描述

4 使用列表推导式实现矩阵转置

对于嵌套了列表推导式的列表推导式,一定要清楚其执行顺序。

matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
print(matrix)
print([[row[i] for row in matrix] for i in range(4)])
# 等价于
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
g = []
for i in range(4):
    g.append([row[i] for row in matrix])
print(g)
# 等价于
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
g = []
for i in range(4):
    temp = []
    for row in matrix:
        temp.append(row[i])
    g.append(temp)
print(g)

在这里插入图片描述

可以使用内置函数 zip() 和 list() 来实现矩阵转置。

matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
print(list(map(list, zip(*matrix))))

在这里插入图片描述

5 列表推导式中可以使用函数或复杂表达式

def func(v):
    if v % 2 == 0:
        v = v ** 2
    else:
        v = v + 1
    return v


print([func(v) for v in [2, 3, 4, -1] if v > 0])
# 等价于
print([v ** 2 if v % 2 == 0 else v + 1 for v in [2, 3, 4, -1] if v > 0])

在这里插入图片描述

6 列表推导式支持文件对象迭代

with open('test.txt', 'r') as fp:
    print([line for line in fp])

在这里插入图片描述

7 使用列表推导式生成 100 以内的所有素数

from math import sqrt

print([x for x in range(2, 100) if 0 not in
       [x % d for d in range(2, int(sqrt(x)) + 1)]])

在这里插入图片描述

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 以下是使用列表推导式生成100以内的所有素数的代码: ``` prime_numbers = [x for x in range(2, 101) if all(x % i != for i in range(2, x))] print(prime_numbers) ``` 解释一下: - `range(2, 101)` 表示从2到100的所有整数,不包括101。 - `all(x % i != for i in range(2, x))` 表示对于从2到x-1的所有整数i,都满足x % i != ,即x不能被2到x-1之间的任何一个数整除。 - `[x for x in range(2, 101) if all(x % i != for i in range(2, x))]` 表示对于从2到100的所有整数x,如果x是素数(即不能被2到x-1之间的任何一个数整除),就把x加入到列表中。 运行上述代码,输出结果为: ``` [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] ``` ### 回答2: 素数是指只能被1和本身整除的正整数,也叫质数。下面使用Python列表推导式生成100以内的所有素数: ```python prime_nums = [i for i in range(2, 101) if all(i % j != 0 for j in range(2, int(i ** 0.5) + 1))] print(prime_nums) ``` 首先,列表推导式的语法是:`[expression for item in iterable if condition]`,其中`expression`表示要生成的元素的表达式,`item`表示可迭代对象中的每个元素,`iterable`表示可迭代对象,`condition`是条件语句,表示要筛选的元素必须满足的条件。 在这个问题中,我们需要生成100以内的素数,所以`iterable`就是一个从2到100的范围,即`range(2, 101)`,然后使用`if`语句来筛选出素数。判断素数的方法是:对于每个数i,判断它是否能被从2到i的平方根范围内的每个数整除。这里使用的是`all`函数,它可以判断一个可迭代对象中的所有元素是否都为真,即所有除数都不能整除i才是素数。 最后,将符合条件的素数通过列表推导式生成一个列表,并输出结果即可。 ### 回答3: 素数是指除了1和它本身以外,没有其他因数的自然数。因此,要生成100以内的所有素数,我们需要用到筛法。 首先,生成一个100以内的正整数列表。然后,从2开始,对列表中的每个数进行筛选,如果一个数是素数,则将它的所有倍数从列表中删除。最后留下的就是100以内的所有素数。 使用列表推导式可以让代码更简洁和易读。代码如下: ```python primes = [x for x in range(2, 101) if all(x % y != 0 for y in range(2, int(x**0.5)+1))] ``` 列表推导式中,`range(2, 101)` 生成了一个包含2到100的正整数列表。`all(x % y != 0 for y in range(2, int(x**0.5)+1))` 用来判断一个数是否为素数。该代码使用了一个常见的优化方法——只需要判断一半就行了,即从2到x的平方根。 最后,生成的 `primes` 列表就是100以内的所有素数。 注意,这种方法虽然对小范围内的素数情况很有效,但对于极大范围的素数问题,一般采用其他更加高效的算法,如米勒-拉宾素性检验等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我还记得那天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值