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 · 4987 次点击
    这是一个创建于 1862 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假设有 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 这可太暴力了
    zh584728
        24
    zh584728  
       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   ·   实用小工具   ·   5322 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:42 · PVG 15:42 · LAX 23:42 · JFK 02:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.