neolee / wop-community

29 stars 19 forks source link

assignment 2 #204

Closed doriawq closed 4 years ago

doriawq commented 4 years ago

翻来覆去睡不着,还是问问老师吧,以下是我一个晚上的思路:

老师教材里有判断一个数是否为质数的函数,可以拿来用 我就按直播的例子写了class primes,初始值为1 写到next方法,觉得偶数可以都排除掉,所以不断加2就好 可是第一个质数2放在哪里?想起老师讲colorbot时用了列表,就把2放到初始列表里 后面迭代可以用append( )把后续元素加进去

然后这个无限元素的列表要怎么切片打印有限个呢? 1596313721(1)

doriawq commented 4 years ago

1596317411(1) 我好像试出来了,至于为什么是8,9 有点费解...

doriawq commented 4 years ago

1596320760(1) 然后generator为什么迭代出来中间有重复的呢 哪里写错了

jiaobufan commented 4 years ago

我大概看了一下发现了几个问题:

jiaobufan commented 4 years ago

我大概看了一下发现了几个问题:

doriawq commented 4 years ago

我大概看了一下发现了几个问题:

这里定义的next方法,返回的下个元素是整个list,而不是下一个素数。 意思就是,你每次都给list里增加一个素数,next方法把整个素数的list都返回了,这也就是上边那个8和9切分的并不是素数列表,而是很多个下一个元素是比上一个元素多一个元素的多个list。因此,你可以遍历输出一下 判断素数,去掉偶数的方法,你每次+2,这个我不太清楚会不会刚好漏掉某个数字,靠谱的做法还是一个一个试验对2取余,然后跳过。 还有你循环遍历的方式也有点问题,你for in 循环中的n在循环体里没有用到。 generator问题基本相似。

什么叫遍历输出呢?为什么generator挂起有重复的,第一个方法没有

jiaobufan commented 4 years ago

我大概看了一下发现了几个问题: 这里定义的next方法,返回的下个元素是整个list,而不是下一个素数。 意思就是,你每次都给list里增加一个素数,next方法把整个素数的list都返回了,这也就是上边那个8和9切分的并不是素数列表,而是很多个下一个元素是比上一个元素多一个元素的多个list。因此,你可以遍历输出一下 判断素数,去掉偶数的方法,你每次+2,这个我不太清楚会不会刚好漏掉某个数字,靠谱的做法还是一个一个试验对2取余,然后跳过。 还有你循环遍历的方式也有点问题,你for in 循环中的n在循环体里没有用到。 generator问题基本相似。

什么叫遍历输出呢?为什么generator挂起有重复的,第一个方法没有

  1. 遍历输出就是用for in循环打印出n
  2. generator有重复的原因是你无论有没有增加元素,都yield lst了,也就是重复return了。
doriawq commented 4 years ago
  1. 为什么是 8,9? 我们要明白:

islice 的返回值是一个 iterator。

这即意味着说:islice(p, 8, 9) 的返回值不是一个列表,而是一个迭代器,这个迭代器只返回一个元素——就是那个列表。所以,for ... in 循环执行一次就会退出。

  1. generator为什么迭代出来中间有重复的呢? 因为你的素数列表无论有无新值加入,每次运行都会返回一个列表,这即意味着说:如果有新值加入,它就返回一个新列表;如果没有新值加入,它就返回原列表——这正是重复的原因所在。

1.为什么是8,9 ——我知道如果写islice(p, 0, 9)会输出一堆列表,写8,9是因为:完全不知道有什么更好的方法可以打印

2.为什么第一种方法islice(p, 0, 9)不重复呢?

3.然后,需要如何改进呢?放弃初始列表这种方法么

neolee commented 4 years ago

看了下代码,我觉得首先要理解这几个关键点:

  1. 可迭代对象的 __next__() 方法每次返回一个数据,所以你写的版本里返回一个列表肯定是不对的。
  2. 针对作业的要求,这个 __next__() 应该做的是:假定 self.base 是一个素数,如何找到紧接着它的下一个素数并返回?

至于二楼的问题,你自己仔细看看就能发现问题:循环体里打印 p.list 的话,和循环变量 n 一点关系都没有,那个循环仅影响了打印执行几次而已,而 islice(p, 8, 9) 不管 p 是啥,都只会返回一个数,循环只执行一次,打印了一个 p.list 出来,这不是“用 for 循环迭代 p”。

neolee commented 4 years ago

@Createitv 先去 https://github.com/neolee/wop-community 学习如何贴代码。

neolee commented 4 years ago

@Createitv 你可以直接修改你前面的回复,不要重复贴啊,这样一大串刷屏了都……

Createitv commented 4 years ago

你的迭代器和生成器生成的是类似这样的列表

lst = [
    [2,3,5],
    [2,3,5,7],
    [2,3,5,7,9],
]

参考代码

from math import sqrt
from itertools import islice

def is_prime(n):
    if n < 2:
        return False
    if n in (2, 3):
        return True
    for i in range(2, int(sqrt(n))+1):
        if n % i == 0:
            return False
    return True

class primes:

    def __init__(self):
        self.base = 1
        # self.list = [2]

    def __iter__(self):
        return self

    def __next__(self):
        while True:
            self.base += 1
            if is_prime(self.base):
                # self.list.append(self.base)
                return self.base

def primes_generator():
    n = 1
    # lst = [2]
    while True: 
        if is_prime(n):
            yield n
        n += 1        
p = primes()
iterator_lst = []
iterator_lst.append(p)
print(list(islice(p,0,10)))
p_g = primes_generator()
for i in islice(p_g,0,10):
    print(i)