2020-11-22

列表推导式、生成器和迭代器

关键词:列表推导式;生成器;迭代器;实例;可迭代;转换迭代器

在创建一个列表、元组或字典时,如果其元素有规律可循,则可以用while或for循环创建。但是,如果该规律简单时,就没有必要用循环创建了。此时,可以选择用推导时创建。
推导式的结构有两种:
1)表达式1 for 变量 in 表达式2
2)表达式1 for 变量 in 表达式2 if 条件

1. 列表推导式

例如,创建一个1到5的自然数列表
lst = [i for i in range(1,6)]
print(lst) >>[1, 2, 3, 4, 5]
又如,创建一个2到10的偶数列表
lst2 = [2*i for i in range(1,6)]
print(lst2) >>[2, 4, 6, 8, 10]
或者
lst3 = [i for i in range(2,11,2)]
print(lst3) >>[2, 4, 6, 8, 10]
或者
lst4 = [even for even in range(1,11,1) if even % 2 ==0]
print(lst4) >>[2, 4, 6, 8, 10]
或者
lst5 = [2 * j + 2 for j in range(0,5,1)]
print(lst5) >>[2, 4, 6, 8, 10]

注意: 变量是来自表达式2的元素,表达式1式关于变量的表达式,表达式1也可以式变量本身。

2. 生成器

创建一个列表后,列表中的每个元素都要分配一个内存空间用于存储。因此,如果一个列表中有很多元素,而在计算运行时需要用到的仅仅是前面几个元素,那么使用如此庞大的列表对内存的需求太大,浪费存储空间,影响计算速度。
为此,如果能够用一个元素就生成一个元素,就能解决存储空间浪费的问题。解决办法:用生成器。创建生成器有两种方法:
方法1.生成器的创建和列表类似,只是将[]换成()即可。
方法2.生成器函数。
另外,调用方法有两种。举例如下:
如:用列表推导式生成一个自然数
gene1 = (i for i in range(1,9))
print(next(gene1)) >> 1
print(gene1.next()) >> 2
如:用生成器函数生成一个自然数
def fn():
i = 0
while True:
i += 1
yield i
g = fn()
print(next(g)) >> 1 #第一次调用为1
print(next(g)) >> 2 #第二次调用为2

注:如果将函数中的return res改为yield res,则该函数就叫生成器函数。
2.1 用type()函数查看生成器的类型

如:
def fn():
i = 0
while True:
i += 1
yield i
g = fn()
print(type(g)) >> <class ‘generator’>

2.2 用isinstance(a,b)函数判断一个对象a是否是另一个对象b的实例

如:print(isinstance(1,int))
print(isinstance(1,int)) >> True #整数实例
print(isinstance(‘1’,str)) >> True #字符串实例
print(isinstance([1,2],list)) >> True #列表实例
print(isinstance((1,2),tuple)) >> True #元组实例
print(isinstance({‘1’:1,‘2’:2},dict)) >> True #字典实例

3. 迭代器

可以被next()函数调用,并不断返回下一个值的对象。

3.1 迭代

获取一个元素的过程叫迭代。

3.2 可迭代对象

包括字符串、列表、集合、元组等,以及生成器。用isinstance(a,Iterable)可判断对象a是否是可迭代的。
如:
from collections.abc import Iterable
print(isinstance([1,2],Iterable)) >> True
print(isinstance((1,2),Iterable)) >> True
print(isinstance({‘1’:1},Iterable)) >> True
print(isinstance(‘abc’,Iterable)) >> True
print(isinstance({1,2},Iterable)) >> True

注意:整数,浮点数,bool值等都是不可迭代的。

from collections.abc import Iterable
print(isinstance(123,Iterable)) >>False
print(isinstance(123.0,Iterable)) >>False
print(isinstance(True,Iterable)) >>False

注意:可迭代的对象不一定都是迭代器,但可以用iter()函数转换为迭代器。

如:
lst = [1,2,3,4]
print(next(lst)) >>TypeError: ‘list’ object is not an iterator
print(type(lst)) >> <class ‘list’> 是因为lst仅仅是一个列表对象。
但是,如果
lst = [1,2,3,4] #lst是个列表
lst = iter(lst) #将列表lst转化为迭代器
print(next(lst)) >>1

注: 生成器就是一种特殊的迭代器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Java 中的 LocalDateTime 类来处理时间。 首先,我们需要将给定的时间段转换为 LocalDateTime 对象: ```java LocalDateTime start = LocalDateTime.of(2020, 11, 20, 0, 0, 0); LocalDateTime end = LocalDateTime.of(2021, 10, 9, 23, 59, 59); ``` 这里将结束时间设置为 23:59:59 是因为我们想要包含该日期的所有时间。 接下来,我们可以使用一个循环来遍历时间段中的每一天,并获取该天的开始时间和结束时间: ```java LocalDateTime current = start; while (!current.isAfter(end)) { LocalDateTime dayStart = current.withHour(0).withMinute(0).withSecond(0).withNano(0); LocalDateTime dayEnd = current.withHour(23).withMinute(59).withSecond(59).withNano(999999999); System.out.println("Day " + current.toLocalDate() + " starts at " + dayStart + " and ends at " + dayEnd); current = current.plusDays(1); } ``` 这里,我们使用 `withHour`、`withMinute`、`withSecond` 和 `withNano` 方法来设置每天的开始时间和结束时间。然后,我们可以使用 `plusDays` 方法来增加 `current` 对象的日期,以便遍历整个时间段。 完整代码如下: ```java import java.time.LocalDateTime; public class Main { public static void main(String[] args) { LocalDateTime start = LocalDateTime.of(2020, 11, 20, 0, 0, 0); LocalDateTime end = LocalDateTime.of(2021, 10, 9, 23, 59, 59); LocalDateTime current = start; while (!current.isAfter(end)) { LocalDateTime dayStart = current.withHour(0).withMinute(0).withSecond(0).withNano(0); LocalDateTime dayEnd = current.withHour(23).withMinute(59).withSecond(59).withNano(999999999); System.out.println("Day " + current.toLocalDate() + " starts at " + dayStart + " and ends at " + dayEnd); current = current.plusDays(1); } } } ``` 输出结果如下: ``` Day 2020-11-20 starts at 2020-11-20T00:00 and ends at 2020-11-20T23:59:59.999999999 Day 2020-11-21 starts at 2020-11-21T00:00 and ends at 2020-11-21T23:59:59.999999999 Day 2020-11-22 starts at 2020-11-22T00:00 and ends at 2020-11-22T23:59:59.999999999 ... Day 2021-10-07 starts at 2021-10-07T00:00 and ends at 2021-10-07T23:59:59.999999999 Day 2021-10-08 starts at 2021-10-08T00:00 and ends at 2021-10-08T23:59:59.999999999 Day 2021-10-09 starts at 2021-10-09T00:00 and ends at 2021-10-09T23:59:59.999999999 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值