关于 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
kevinfk2
V2EX    Python

关于 Python 表达包含与被包含的语法

  •  
  •   kevinfk2 2020-12-18 10:36:15 +08:00 3475 次点击
    这是一个创建于 1833 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如两个数据对比

    A: aabbcc

    B: abbc

    如果 A 包含 B,就输出 。

    用什么表达语法啊

    新手求解,大佬莫怪
    第 1 条附言    2020-12-18 14:24:59 +08:00
    首先感谢各位大佬的耐心解答。但是新手看完回答后还是很懵。我改成一个实际的例子说明吧。

    现在有两个 excel 。

    excel A 的数据是 https://imgur.com/qv4tUV9
    excel B 的数据是 https://imgur.com/0hLpmRJ

    现在我需要用 A 去和 B 对照,找出两个表类类似的数据(就是 A 和 B 两个表中有的名字是完全一样的,有的是不完全一样的)。

    我现在用的代码是
    # -*- coding: utf-8 -*-
    from __future__ import print_function

    import xlrd

    file1 = r'C:\Users\140082\Desktop\test_待检测数据.xlsx' # 待检测文件路径
    file2 = r'C:\Users\140082\Desktop\test_对照表格.xlsx' # 对照文件路径

    def compare(file1, file2):
    nickName = [] # 存放所有不存在的数据在待检测表格中的索引
    wb1 = xlrd.open_workbook(file1) # 打开待检测 xlsx 文件
    wb2 = xlrd.open_workbook(file2) # 打开对照 xlsx 文件
    sheet1 = wb1.sheet_by_index(0) # 参数 0 是索引,表示 wb1 这个文件的第一张表格
    sheet2 = wb2.sheet_by_index(0) # 和上同理
    for i in sheet1.col_values(0): #遍历 sheet1 中第一列每一项

    if i in sheet2.col_values(0): #查看是否在 sheet2 第一列中

    nickName.append(i)
    return nickName #返回的是不存在于 sheet2 中的数据的第一列的值的列表
    print(compare(file1, file2))

    运行后,只有两个表完全一样的数据才输出了。怎么改进能得到我想要的结果呢?
    38 条回复    2020-12-21 11:24:27 +08:00
    destinism
        1
    destinism  
       2020-12-18 10:53:35 +08:00
    B in A 吧
    galileo1214
        2
    galileo1214  
       2020-12-18 10:55:22 +08:00
    isin
    whitefox027
        3
    whitefox027  
       2020-12-18 10:58:46 +08:00
    if B in A :
    kevinfk2
        4
    kevinfk2  
    OP
       2020-12-18 10:59:17 +08:00
    @destinism B in A 好像只能对比完全一致的两个数据,我想对比的是两个类似的数据。不知道用什么表达好
    zeroDev
        5
    zeroDev  
       2020-12-18 11:00:44 +08:00 via Android
    @kevinfk2 #4 就是这样用的,你自己试试
    ly4572615
        6
    ly4572615  
       2020-12-18 11:01:26 +08:00
    那用正则吧
    kevinfk2
        7
    kevinfk2  
    OP
       2020-12-18 11:01:45 +08:00
    @galileo1214 我试试
    ly4572615
        8
    ly4572615  
       2020-12-18 11:02:14 +08:00
    或者 find()方法
    kevinfk2
        9
    kevinfk2  
    OP
       2020-12-18 11:07:04 +08:00
    @ly4572615 不太会我找找用法试下先
    destinism
        10
    destinism  
       2020-12-18 11:07:44 +08:00
    @kevinfk2 那只能正则了
    LiKanKan
        11
    LiKanKan  
       2020-12-18 11:09:53 +08:00 via Android
    A:str = "aabbcc"
    B:str = "abbc"
    if A.find(B) == -1:
    #找不到为-1,如果找到则为第一个出现的位置
    print("B is not in A")
    else:
    print("A contains B")
    kevinfk2
        12
    kevinfk2  
    OP
       2020-12-18 11:20:13 +08:00
    @LiKanKan 那如果是对 list 而言的话,该怎么用啊
    HashV2
        13
    HashV2  
       2020-12-18 11:52:07 +08:00
    @kevinfk2 如果你是只是想无序的判断 B 列表内所有的元素在不在另 A 列表中遍历就好了:
    all([ele in A for ele in B])
    如果想有序判断可以先在 A 中找到 B 的第一个元素的所有的索引
    按照 B 的长度从索引切片后和 B 比较,如果有一个为真就是有序包含了
    LiKanKan
        14
    LiKanKan  
       2020-12-18 12:08:47 +08:00 via Android   1
    @kevinfk2 如果是 List[str]可以用"".join(A 或 B)转化成上面一种情况。如果包含其他种类元素:如果连续有序,就手写子串匹配;如果不连续有序,就遍历 B,对着 A 的元素找;如果不连续也不有序,反之,对遍历 A 找 B
    no1xsyzy
        15
    no1xsyzy  
       2020-12-18 12:38:56 +08:00
    @HashV2 把方括号去掉获得空间和时间提升( compl 换成 compg,不需要存储整个 list,第一个为 False 的地方直接退出)
    当然,从可读性上来说,如果都是 hashable 的话,推荐 set(A) > set(B)

    @kevinfk2 list 就是正常手写循环啊(
    的确有双层 compg 的黑魔法,但可读性太垃圾了。
    009694
        16
    009694  
       2020-12-18 12:56:59 +08:00 via iPhone
    为啥要用 find 不用 in 。。find 比 in 慢得多 (从 js 转的还是 java 转的?
    JeffGe
        17
    JeffGe  
       2020-12-18 13:19:26 +08:00
    >>> A = [1, 1, 2, 2, 1, 1]
    >>> B = [1, 2, 2, 1]
    >>> str(B)[1:-1] in str(A)
    True
    kevinfk2
        18
    kevinfk2  
    OP
       2020-12-18 14:28:06 +08:00
    @LiKanKan 看了下还没弄明白,我加了附言,可能更方便你帮我解答,有时间的话帮我看看呗
    ipwx
        19
    ipwx  
       2020-12-18 14:42:51 +08:00
    你需要某种字符串相似度计算的算法,比如编辑距离( edit distance )

    https://leetcode.com/problems/edit-distance/
    https://pypi.org/project/editdistance/0.3.1/
    ipwx
        20
    ipwx  
       2020-12-18 14:44:07 +08:00
    在做一些根据先验知识的预处理。比如后缀“有限公司”或者“公司”就先全部删掉。
    JeffGe
        21
    JeffGe  
       2020-12-18 14:47:23 +08:00 via Android   1
    if any(i in s2 for s2 in sheet2.col_values(0)):
    owtotwo
        22
    owtotwo  
       2020-12-18 14:48:44 +08:00 via Android   1
    你得先定义什么是“相似” 再谈其他的
    kevinfk2
        23
    kevinfk2  
    OP
      nbsp;2020-12-18 14:55:52 +08:00
    @JeffGe 感谢大佬,出效果了 十分感谢!
    lanshee
        24
    lanshee  
       2020-12-18 14:59:57 +08:00
    if A in B or B in A 这样行不?
    kevinfk2
        25
    kevinfk2  
    OP
       2020-12-18 15:02:34 +08:00
    @lanshee 好像不行吧 我没试 in 好像都是查完全一致的才行
    sudoy
        26
    sudoy  
       2020-12-18 15:04:12 +08:00
    我看你好像只遍历一个数据,两个都要遍历。

    ```
    a = ['苹果', '橘子', '香蕉', ‘葡萄’]
    b = ['苹果', ‘越南橘’, '香蕉', '椰子']

    c = []
    for x in a:
    for y in b:
    if x == y:
    c.append(x)
    ```
    sudoy
        27
    sudoy  
       2020-12-18 15:09:26 +08:00
    或者

    a = ['苹果', '橘子', '香蕉', ‘葡萄’]
    b = ['苹果', ‘越南橘’, '香蕉', '椰子']
    c = [x for x in a if x in b]

    c 应该就是你要找的
    sudoy
        28
    sudoy  
       2020-12-18 15:10:30 +08:00
    >>> a = ['apple', 'orange', 'banana']
    >>> b = ['apple', 'grape', 'banana']
    >>> c = [x for x in a if x in b]
    >>> c
    ['apple', 'banana']
    sudoy
        29
    sudoy  
       2020-12-18 15:20:20 +08:00   1
    如果你要模糊匹配,可以为:

    >>> a = ['apple', 'orange', 'banana']
    >>> b = ['apple', 'grape', 'fresh banana']
    >>> c = []
    >>> for x in a:
    ...............for y in b:
    ........................if x == y or x in y:
    ...............................c.append(x)
    lanshee
        30
    lanshee  
    &bsp;  2020-12-18 15:21:02 +08:00
    @sudoy 你这个少遍历了吧,这个是全量匹配了.他的需求应该是当前单词在不在另一组的单词里,而不是在另一组里
    sudoy
        31
    sudoy  
       2020-12-18 15:28:35 +08:00
    @lanshee 嗯,我前面没看清楚,最后一个回复里面考虑到得了。不过这里面还有特殊字符的问题,另外还有可能要把名字拆开匹配,比如“某某公司”和“某某有限责任公司”属于同一家公司,那么就要把前面拆成四个字,后面拆成八个字,如果后面那八个字都包含前面四个字,就是满足条件
    duzhor
        32
    duzhor  
       2020-12-18 15:28:38 +08:00
    你这个 if 的意思是如果 sheet1 的元素在 sheet2 的列表里面。所以要加一层 for 去遍历 sheet2,再把 sheet1 里的每个元素依次跟 sheet2 里的每个元素比较。
    TimePPT
        33
    TimePPT  
    PRO
       2020-12-18 15:40:47 +08:00   1
    字符串匹配策略遇到
    翰硕电子 | 翰子
    这种 case 你没法解的
    est
        34
    est  
       2020-12-18 15:49:01 +08:00
    @TimePPT 正解了。

    所以 LZ 这个事其实还是手动做的好。。
    79lawyer
        35
    79lawyer  
       2020-12-18 15:50:20 +08:00
    BTW,处理 Excel 试试 pandas
    kevinfk2
        36
    kevinfk2  
    OP
       2020-12-18 16:02:38 +08:00
    @est 这只是个例子 要处理的数据有几 w 个
    krixaar
        37
    krixaar  
       2020-12-18 17:22:00 +08:00
    如果真的只是差“有限公司”或者“有限责任公司”这样,可以直接把另一边的数据先处理了再比对。
    问题是规则是不是就这么简单,比如碰到农行、农发行、农业银行、农业发展银行这样的。
    HelloViper
        38
    HelloViper  
       2020-12-21 11:24:27 +08:00
    以前的公司名匹配度算法供参考:
    https://github.com/verarong/CompanyNameMatch
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2768 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 14:54 PVG 22:54 LAX 06:54 JFK 09:54
    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