作者回复: 第一个问题,这里使用 %12 取模的原因是当输入的元组范围大于12月23日,取得的元组长度为12 在python中有12个元素的元组下标是0-11,而不是我们常见的1-12,因此使用和12求模的方式 避免下标越界,可以去掉%12就能看的运行结果的区别了,可以参考如下例子 a = (1, 2, 3, 4, 5, 6) print(len(list(a))) # 输出结果是6 a[6] # 抛出异常,下标越界了 IndexError: tuple index out of range len(list(a))%6 # 和6求模运算,输出0 a[0] # 取第一个元素 1 第二个问题,取模(mod)和求余(rem)是不同的,但因为大部分编程语言里,都使用%表示取模和求余,导致大家混淆了它们的用法。正如你看到的结论一样,在a % b 运算中,如果 a、b符号相同,取模和求余结果相同;如果符号不同,取模和求余的结果是不同的,比如C语言的%就是求余,Python语言的%就是取模。
作者回复: 这位同学非常的细心,第二次调用返回的确是空值。 这里使用的filter()函数的返回类型叫迭代器,它是我们后面要讲的一种函数功能。 filter函数返回的内容类似一根长长的管子,里面按顺序依次存好要输出的元素,使用list()函数可以一次性将管子里的数据都取出来,第二次再去取管子中自然是空的了。 当然也可以使用__next__()函数每次只取一个元素,根据业务的需要来编写。 import time num = [1, 2, 3, 4, 5, 6] a = iter(num) # 把列表转换成迭代器 # 对比一下num 和 a的类型 print(type(num)) print(type(a)) # 输出 print(list(a)) # 一次返回所有内容 print(list(a)) # 空了 # 同样功能的filter()函数 b = filter(lambda x: x <= 5, num) print(b.__next__()) # 取第一个 print(b.__next__()) # 取第二个 print(list(b)) # 全取出来 time.sleep(1) # 停1秒方便观察 b.__next__() # 返回一个StopIteration异常,告诉用户已经没有可以取得内容了
作者回复: NICE!能够自己发现并解决只有一个元素的元组问题非常棒,可以自己尝试用type()print()查看和输出一下,带,和不带,的区别
作者回复: 这里使用的filter()函数的返回类型叫迭代器,它是我们后面要讲的一种函数功能。 filter函数返回的内容类似一根长长的管子,里面按顺序依次存好要输出的元素,使用list()函数可以一次性将管子里的数据都取出来,第二次再去取管子中自然是空的了。 当然也可以使用__next__()函数每次只取一个元素,根据业务的需要来编写。 import time num = [1, 2, 3, 4, 5, 6] a = iter(num) # 把列表转换成迭代器 # 对比一下num 和 a的类型 print(type(num)) print(type(a)) # 输出 print(list(a)) # 一次返回所有内容 print(list(a)) # 空了 # 同样功能的filter()函数 b = filter(lambda x: x <= 5, num) print(b.__next__()) # 取第一个 print(b.__next__()) # 取第二个 print(list(b)) # 全取出来 time.sleep(1) # 停1秒方便观察 b.__next__() # 返回一个StopIteration异常,告诉用户已经没有可以取得内容了
作者回复: 我说一下我解决这个问题的思路吧 首先看到报错,我认为问题首先出现在 x <= (month, day) 这里,所以把程序做了简化 zodiac_days = ( (1, 20), (2.19), (3, 21), (4, 21), (5, 21), (6, 22), (7, 23), (8, 23), (9, 23), (10, 23), (11, 23), (12, 23)) (month, day) = (2, 15) zodiac_day = filter(lambda x: x <= (month, day), zodiac_days) list(zodiac_day) 依然报错,证明之前的猜测是正确的,那继续将程序精简成伪代码分析逻辑 定义 zodiac_days = ( (1, 20), (2.19), (3, 21), (4, 21), (5, 21), (6, 22), (7, 23), (8, 23), (9, 23), (10, 23), (11, 23), (12, 23)) 定义 (month, day) = (2, 15) 逐个比较 zodiac_days <= (month, day) 找到 一个是tuple 和 float 格式进行比较 这样就很容易定位到 (2.19) 不是tuple类型, 是浮点类型 所以问题是书写错误, 应该是(2,19) 不是 (2.19)
作者回复: filter() 对象取出来的内容,可以当作是”一次性“的,list()操作之后,里面就是空值,所以每次得到的结果不同
作者回复: 使用type()查看一下zodiac_day会发现它的类型是一个迭代类型,当你去取迭代类型的数据时,相当于把里面的内容拿走了,它存储的内容为空,自然统计长度变成第一个,即你看到结果。
作者回复: 注意一下zodiac_day的类型,它的返回值是“生成器类型”,它的特点是逐个取出,取出之后里面的内容就是“空的”了。
作者回复: x<=(month,day) 得到 list(zodiac_day) 是 [(1, 20)] ,后面len(list(zodiac_day)) 计算的结果 1 ,所以 得到最终的结果就是 print(zodiac_name[1]) == 水瓶座了
作者回复: 结果不同是因为这里使用了一个filter()函数,它比较特殊,它的返回类型叫迭代器,是我们后面要讲的一种函数功能。 filter函数返回的内容类似一根长长的管子,里面按顺序依次存好要输出的元素,使用list()函数可以一次性将管子里的数据都取出来,第二次再去取管子中自然是空的了。所以第二次执行时返回结果为0