Python 如何从一个文本中取每一行到另外一个文本中匹配 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zhuzhuaini
V2EX    Python

Python 如何从一个文本中取每一行到另外一个文本中匹配

  •  
  •   zhuzhuaini 2019-11-21 16:32:43 +08:00 5388 次点击
    这是一个创建于 2181 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假设有 A/B 两个文本 用 python 如何先从 A 中取出第一行 然后到 B 文本中每一行去匹配,如果匹配中了就啥也不干继续从 A 文本中取下一行匹配,如果在 B 文本中每一行都没匹配到,就输出 A 文本中第一行的数据然后继续去 A 文本中下一行去匹配
    研究了一会发现不能达到自己的预期,特来请教.谢谢!
    33 条回复    2019-11-22 13:13:28 +08:00
    ClericPy
        1
    ClericPy  
       2019-11-21 16:38:04 +08:00   2
    需要掌握打开文件按行读取的 file.readline()
    需要用到调整文件读取指针位置的 file.seek(0)
    然后迭代器开几个 for 循环的函数, 共享已经打开的 A 和 B 俩文件就好了, 一般是在一个 with 下面俩文件对象, 然后写一个函数, 传参 line_text, file_object, 因为是迭代器, 内存占用还算可以接受

    按你提的方式, 性能也高不到哪去了, 不过比现写个前缀树要省心多了
    ClericPy
        2
    ClericPy  
       2019-11-21 16:38:45 +08:00   1
    忘了 file_object 可以直接丢到 for, 不需要 readline...
    cherbim
        3
    cherbim  
       2019-11-21 16:40:48 +08:00 via iPhone   1
    这不很简单,先 a.readline(),然后循环对比 b.readline()
    cherbim
        4
    cherbim  
       2019-11-21 16:44:45 +08:00 via iPhone   1
    你的需求是不是把 a 中未在 b 中出现的每一行输出?
    zhuzhuaini
        5
    zhuzhuaini  
    OP
       2019-11-21 16:51:49 +08:00
    @ClericPy 不是很理解你说的,,,我学的还不够~
    zhuzhuaini
        6
    zhuzhuaini  
    OP
       2019-11-21 16:52:37 +08:00
    @cherbim 是的 A 中未在 B 出现的那一会 就打印 出现了 就啥也不干继续从 A 中取一行继续去 B 匹配
    zhuzhuaini
        7
    zhuzhuaini  
    OP
       2019-11-21 16:52:55 +08:00
    @ClericPy 刚学 python 先不去考虑性能啥的~~~
    ipwx
        8
    ipwx  
       2019-11-21 16:55:31 +08:00   1
    with open('B.txt', 'r') as f:
    ....B_lines = set(f)
    with open('A.txt', 'r') as f:
    ....for line in f:
    ........if line not in B_lines:
    ............print(line)
    cherbim
        9
    cherbim  
       2019-11-21 17:01:16 +08:00   1
    第一感觉就是新手,果然是新手。。。。
    @zhuzhuaini 给你个代码吧,下面的代码,按行读取 1.txt 内容,然后按行与 2.txt 中比对,若不存在就输出,继续读取 1.txt
    ~~~
    with open("1.txt", "r") as f:
    while True:
    i = f.readline()
    if i:
    with open("2.txt", "r") as file:
    while True:
    j = file.readline()
    if j:
    if i == j:
    break
    else:
    print(i, end="")
    break
    else:
    break
    ~~~
    ClericPy
        10
    ClericPy  
       2019-11-21 17:07:41 +08:00   1
    @zhuzhuaini #7

    https://paste.ubuntu.com/p/W6Qq4mtjfv/

    如果是面试题, 这段代码基本涵盖所有考点了, 但是很多小细节有炫技嫌疑...

    1. with 打开文件保证安全关闭
    2. seek 方法保证只需要打开一次文件 B 不需要多次打开
    3. 对文件对象 A B 使用 for 循环, 节省内存
    4. for 循环的 else 用法
    5. with 上下文一次打开多个文件
    cherbim
        11
    cherbim  
       2019-11-21 17:09:06 +08:00   1
    你先试着用 readline(),完整的输出一个文件(一行一行输出),理解了这个,你的需求就很容易解决了
    nznd
        12
    nznd  
       2019-11-21 17:09:26 +08:00   2
    with open('1.txt', 'r') as f, open('2.txt', 'r') as ff:
    a = set(f)
    b = set(ff)
    print(a-b)
    简单粗暴(
    nznd
        13
    nznd  
       2019-11-21 17:09:54 +08:00   1
    @nznd #12 缩进丢了 但是应该看的出来吧(狗头
    zhuzhuaini
        14
    zhuzhuaini  
    OP
       2019-11-21 17:11:49 +08:00
    @cherbim 刚刚在调试你传的代码,,,光缩进就调整了一段时间, 执行之后报错
    i = f.readline()
    UnicodeDecodeError: 'gbk' codec can't decode byte 0x93 in position 15: illegal multibyte sequence
    zhuzhuaini
        15
    zhuzhuaini  
    OP
       2019-11-21 17:12:08 +08:00
    @ClericPy 谢谢 不是面试题 纯是自己有这个需求~
    zhuzhuaini
        16
    zhuzhuaini  
    OP
       2019-11-21 17:12:33 +08:00
    @nznd 太简单粗暴了,导致看不懂 谢谢老哥了哈~~~~
    nznd
        17
    nznd  
       2019-11-21 17:16:51 +08:00   1
    zhuzhuaini
        18
    zhuzhuaini  
    OP
       2019-11-21 17:17:23 +08:00
    @cherbim 谢谢 我加入了 encoding='UTF-8' 这个参数后就不报错了 虽然不知道为啥要加这个-.-
    zhuzhuaini
        19
    zhuzhuaini  
    OP
       2019-11-21 17:17:46 +08:00
    @nznd 听到数学,,我哭辽
    miemiekurisu
        20
    miemiekurisu  
       2019-11-21 17:22:39 +08:00   2
    两个 readlines 成 2 个 list,set 一下成 2 个集合,把两个集合 intersection 一下,就是共有部分,要知道具体哪几行就拿着 intersection 出来的结果每一个去 iteration 一遍第二个文本
    alex321
        21
    alex321  
       2019-11-21 17:24:16 +08:00   1
    提取的是 A 中有的,B 中没有的。。

    a, b = [], []

    with open('A.txt', 'r') as f:
    ....a = f.read().splitlines()
    with open('B.txt', 'r') as f:
    ....b = f.read().splitlines()

    print(list(set(a).difference(set(b))))

    完事儿。
    cherbim
        22
    cherbim  
       2019-11-21 17:38:20 +08:00   1
    @zhuzhuaini 你的文件是 UTF-8 编码,然后估计你的 ide 默认 gbk,然后有些字符不能解码,需要指定 utf 解码
    JerryCha
        23
    JerryCha  
       2019-11-21 17:57:02 +08:00   1
    @nznd 这可太暴力了
    LuJason
        24
    LuJason  
       2019-11-21 18:01:29 +08:00   1
    @nznd 万一是几百万行的数据,这可就要算到明年了(狗头
    bequt
        25
    bequt  
       2019-11-21 20:06:35 +08:00   1
    如果是要结果的话, 直接用 wps excel 马上就得了
    bequt
        26
    bequt  
       2019-11-21 20:09:13 +08:00   1
    进行查重就的结果了
    layorlayor
        27
    layorlayor  
       2019-11-21 20:31:55 +08:00   1
    用一个特殊的字符把 B 文件连成一行,剩下就是一个 AC 自动机啦
    snoopygao
        28
    snoopygao  
       2019-11-21 22:18:58 +08:00   1
    这个东西我刚研究过,首先在 A 中取出第一行,然后使用字符串对比就行
    with open file_b as b:
    b_cOntent= b.read()
    with open file_a as a:
    a_cOntent= a.readline()
    if a_content in bcontent:
    print('this line in b')
    //此处需要循环读 a 文件的内容,b 文件最好别太大,要不然内存耗不起
    robinlovemaggie
        29
    robinlovemaggie  
       2019-11-21 22:45:37 +08:00   1
    @zhuzhuaini
    你好忘了说你的预期是什么~
    nccer
        30
    nccer  
       2019-11-22 01:46:57 +08:00 via iPhone   1
    你可以对 ab 两个文件分别排序,然后对 ab 两个文件做一个归并排序,做排序的时候把重复行找出来。
    XavierXJ
        31
    XavierXJ  
       2019-11-22 10:11:44 +08:00 via iPhone   1
    什么学校???高中学 Python
    levelworm
        32
    levelworm  
       2019-11-22 11:25:54 +08:00 via Android   1
    我琢磨着数据量不大的话导入到 sqlite 里头做查询怎么样。。。
    zhuzhuaini
        33
    zhuzhuaini  
    OP
       2019-11-22 13:13:28 +08:00
    @miemiekurisu
    @levelworm
    @XavierXJ
    @nccer
    @robinlovemaggie
    @layorlayor
    @bequt
    @zh584728
    @alex321
    @miemiekurisu
    感谢以上所有的大佬提供的方案......我最后使用了
    @ClericPy 这位大佬的代码...从昨天下午到刚刚一直在调试,,,最后发现是 for 下接了个 else,,,我一直在 if 下接 else 导致一直不对,现在已经达到了我的心理预期....
    再次感谢以上所有大佬!!谢谢!!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2502 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 15:27 PVG 23:27 LAX 07:27 JFK 10:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86