鱼C论坛

 找回密码
 立即注册
查看: 1974|回复: 9

[已解决]第29讲课后作业动动手1题的小问题

[复制链接]
发表于 2020-11-1 22:00:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这是课后作业29讲动动手的1题
for line1 in f1:
        line2 = f2.readline()
        count += 1
        if line1 != line2:
            differ.append(count)
这是小甲鱼(lsp)的代码,我比较迷惑的是为什么一定要用line2=f2.readline(),然后下面是line1 != line2,结果如图一
我尝试直接f2.readline(),然后后面 line1!=f2.readline(),但是这样它打印出来的结果是错误的,如图二
最后我直接在python中进行写,发现好像第二种方法是可以行的通的,如图三,是可以直接将f2.readline()给提取出来
求大佬解释一下,把我捞出思维误区
最佳答案
2020-11-2 17:22:38
辛荑啊 发表于 2020-11-2 10:31
我会弄了,这就是我的代码,您可以看一下

两个问题,看代码的注释:
file=str(input('请输入需要比较的头一个文件:'))
file1=str(input('请输入需要比较的另一个文件:'))
count=0
list=[]
a=open(file)
b=open(file1)
for each_line in a:
#    b.readline()                    <--这个readline()没有实际意义,没有赋值,只会把文件指针下移一行,所以要去掉
    count+=1
    if each_line != b.readline():     #这个会读取一行,如果有上面的readline(),这里依次读取的是2、4、6、8等等偶数行的内容,去掉上面那行后,这里就和a的每行同步了
        list.append(count)

length=len(list)
if length==0:
    print('两个文件相同')
else:
    print('两个文件共有【%d】处不同:\n'%length)
    for i in list:
#        print('第%d行不一样'%count)      <--这个问题很明显了,改成下面的就OK了
        print('第%d行不一样'%i)

a.close()
b.close()

图一

图一

图二

图二

图三

图三
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-11-2 00:18:26 | 显示全部楼层
本帖最后由 阿奇_o 于 2020-11-2 00:21 编辑

折腾有点久,建议拿两个简单的txt文件来比较,如,ABC,xyz, 123 这样的 ^_^
代码如下,
# 题目:如何比较两个文件的各行是否对应相同
print('\n\n-------方法1---------')
# 方法1:(非对称性地不完美比较,只以f1做依据,不考虑f2中的行数或多或少的情况,只拿f1中有的行来比)
f1 = open('record1.txt')
f2 = open('record2.txt')
count = 0
for e1 in f1:
    e2 = f2.readline()
    if e1 != e2:
        count += 1
        print('%s | %s' %(e1.replace('\n', '\\n'), e2.replace('\n', '\\n')))

print('有%s行不同。' % count) 

print('\n\n-------方法2---------')

# 方法2:(完美地比较对应的每一行)
import linecache
# l1 = linecache.getline('record1.txt', 2) # 指定读取某一行
# print(l1)

n1 = len(open('record1.txt').readlines()) #统计共有多少行
n2 = len(open('record2.txt').readlines())
count = 0
print('注意:文件1共有%s行,文件2共有%s' %(n1, n2))
print('若有不同,对比如下:')
if n1 >= n2:
    for i in range(1, n1+1): # 若文件1的行数更多或相等,则以其为循环次数(保证每一行都对应进行比较)
        e1 = linecache.getline('record1.txt', i)
        e2 = linecache.getline('record2.txt', i)
        if e1 != e2:
            count += 1
            print('%s | %s' %(e1.replace('\n', '\\n'), e2.replace('\n', '\\n')))
else:
    for j in range(1, n2+1): # 相反,若文件2的行数更多,则以它为循环次数的依据
        e1 = linecache.getline('record1.txt', j)
        e2 = linecache.getline('record2.txt', j)
        if e1 != e2:
            count += 1
            print('%s | %s' %(e1.replace('\n', '\\n'), e2.replace('\n', '\\n')))

print('=====共有%s行不同。======' % count) 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-2 02:01:07 | 显示全部楼层
这里涉及到文件指针问题,先从小甲鱼的代码分析:
for line1 in f1:         #遍历f1的每行
        line2 = f2.readline()     #读取f2的当前行,读取后文件指针指到下一行,和f1中读取的行号同步
        count += 1        #计算行号
        if line1 != line2:       #f1的当前行和f2的当前行内容比较
            differ.append(count)       #不同就把行号记录到列表differ中
其实可以考虑简化一下代码,就像你后面的一样,省掉line2这个变量,直接比较内容:
for line1 in f1:
        count += 1
        if line1 !=f2.readline():     #直接读取f2当前行的内容,读完后文件指针指向下一行
            differ.append(count)
这样写程序也能正常运行,记住每次for循环中f2的readline()只能执行一次。
所以现在就不明白图2的运行结果是怎么来的,如果是按你描述的情况似乎时多了一行readline(),例如像这样:
for line1 in f1:
        f2.readline()
        count += 1
        if line1 != line2:
            differ.append(count)
循环中两次readline()导致对比时f2读取的内容是隔行之后的,当然不会与f1的内容相符了,但是这样的结果会是32处不同,列表是从1到32行,而不是图片中的每处都是显示第32行。所以你最好上传一下你的代码,才能分析出到底出了什么问题。
PS:上传代码最好点击图标中的尖括号上传。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-2 10:26:48 | 显示全部楼层
txxcat 发表于 2020-11-2 02:01
这里涉及到文件指针问题,先从小甲鱼的代码分析:

其实可以考虑简化一下代码,就像你后面的一样,省掉li ...

您的第二种方法我试了是没有问题的,我的代码和小甲鱼的基本上差不多,只是他是定义的函数,我是直接写的,然后其中的不同就只有这个for循环不一样,我的for循环中的if判断是  line1 != f2.readline(),不是像您第三个代码中的  line1 != line2,其余都和您第三个代码相同
然后我不懂怎么上传我的代码,我都是粘贴复制的,像您这种我确实不会弄
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-2 10:31:59 | 显示全部楼层
txxcat 发表于 2020-11-2 02:01
这里涉及到文件指针问题,先从小甲鱼的代码分析:

其实可以考虑简化一下代码,就像你后面的一样,省掉li ...
file=str(input('请输入需要比较的头一个文件:'))
file1=str(input('请输入需要比较的另一个文件:'))
count=0
list=[]
a=open(file)
b=open(file1)
for each_line in a:
    b.readline()
    count+=1
    if each_line != b.readline():
        list.append(count)

length=len(list)
if length==0:
    print('两个文件相同')
else:
    print('两个文件共有【%d】处不同:\n'%length)
    for i in list:
        print('第%d行不一样'%count)

a.close()
b.close()

我会弄了,这就是我的代码,您可以看一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-2 10:33:58 | 显示全部楼层
阿奇_o 发表于 2020-11-2 00:18
折腾有点久,建议拿两个简单的txt文件来比较,如,ABC,xyz, 123 这样的 ^_^
代码如下,

啊,您这个第二种方法我当时查到过,但是那个课后作业没有教这些用法,所有我就没用这些写,然后就按第一种写的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-2 11:04:40 | 显示全部楼层
辛荑啊 发表于 2020-11-2 10:33
啊,您这个第二种方法我当时查到过,但是那个课后作业没有教这些用法,所有我就没用这些写,然后就按第一 ...


我的第二种方法,其实也是第一种的优化版,只是借用了一个更实用的模块(可以简单指定读某一行,并支持更大的文件处理)。
不用linecache模块的getline方法,用非对称比较两遍,即用f.readline(),对于小文件也完全可以的。
只是用f.readline()需要理解指针是如何读取(从哪开始逐行读,怎么结束,最后会怎样)
OK, ^_
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-2 11:34:10 | 显示全部楼层
辛荑啊 发表于 2020-11-2 10:31
我会弄了,这就是我的代码,您可以看一下

你在5楼的这个程序与小甲鱼的程序的区别就是,你的程序每次循环,a文件读一行,b文件读了两行。因为每出现一次b.readline()就会读取一行,你把第8行删掉就和小甲鱼用line2的程序一样的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-2 17:22:38 | 显示全部楼层    本楼为最佳答案   
辛荑啊 发表于 2020-11-2 10:31
我会弄了,这就是我的代码,您可以看一下

两个问题,看代码的注释:
file=str(input('请输入需要比较的头一个文件:'))
file1=str(input('请输入需要比较的另一个文件:'))
count=0
list=[]
a=open(file)
b=open(file1)
for each_line in a:
#    b.readline()                    <--这个readline()没有实际意义,没有赋值,只会把文件指针下移一行,所以要去掉
    count+=1
    if each_line != b.readline():     #这个会读取一行,如果有上面的readline(),这里依次读取的是2、4、6、8等等偶数行的内容,去掉上面那行后,这里就和a的每行同步了
        list.append(count)

length=len(list)
if length==0:
    print('两个文件相同')
else:
    print('两个文件共有【%d】处不同:\n'%length)
    for i in list:
#        print('第%d行不一样'%count)      <--这个问题很明显了,改成下面的就OK了
        print('第%d行不一样'%i)

a.close()
b.close()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-2 19:32:47 | 显示全部楼层
sunrise085 发表于 2020-11-2 11:34
你在5楼的这个程序与小甲鱼的程序的区别就是,你的程序每次循环,a文件读一行,b文件读了两行。因为每出 ...

感谢大佬,懂了懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-18 00:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表