作者回复: 第一个问题,这里使用 %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异常,告诉用户已经没有可以取得内容了
作者回复: 这里使用的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() 对象取出来的内容,可以当作是”一次性“的,list()操作之后,里面就是空值,所以每次得到的结果不同
作者回复: 可能在某些缩进上不同,导致执行的顺序有差异,可以先使用print函数打印上一步的执行结果,观察输出是否按你的思路执行的
作者回复: 使用type()查看一下zodiac_day会发现它的类型是一个迭代类型,当你去取迭代类型的数据时,相当于把里面的内容拿走了,它存储的内容为空,自然统计长度变成第一个,即你看到结果。
作者回复: 这里使用星座这个案例是因为学习的一般规律是,根据熟悉的事物迁移到不熟悉的事物;设置的元组嵌套也是为了在没有学习for循环之前可以依次处理每个元素。在你已经掌握for循环时可以考虑处理生活中更多的需要序列类型保存的实际文本,不必拘泥于星座生肖的判断。当然了细心是非常重要的,能够精确控制自己的程序,对用户的输入做准确判断是程序员的必备技能之一,继续加油吧!
作者回复: 注意一下zodiac_day的类型,它的返回值是“生成器类型”,它的特点是逐个取出,取出之后里面的内容就是“空的”了。
作者回复: 不是命名方式,是一种数据类型,就像字符串、整数、列表、字典一样,例如 “123”就是把123当做字符串处理 ,直接使用 123 就是一个整数类型
作者回复: 这里演示更多是为了元组而用元组,其实元组有很多更号的用处的,比如可以作为字典的key,作为函数的返回值, 这类“需要不可变”的类型时来使用,因为初次接触所以用它来存了月份和日期,没有体现出元组的效率更高的特性。
作者回复: n=0
for i in zodiac_name:
print("第" + str(n) + "个元素是" + i)
n += 1
作者回复: (9.23) 这里应该是 (9,23)
作者回复: 我说一下我解决这个问题的思路吧
首先看到报错,我认为问题首先出现在 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()取出来的并不是一个字符串,而是一个“迭代器”,取出一次之后里面的内容就消失了,后面视频会解释这里提前挖好的“坑”