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
songdg
V2EX  ›  Python

除了写循环还有什么更好的办法

  •  
  •   songdg · 2018-05-21 18:49:15 +08:00 · 5050 次点击
    这是一个创建于 2413 天前的主题,其中的信息可能已经有所发展或是发生改变。
    要验证 b 是否在 a 中,除了写循环还有什么更好的办法?
    a = array([False, False, False, True, True, True, False, False, False, False, False, False])
    b = array([True, True, True])
    i = 0
    while True:
    if np.all(b == a[i:i+3]) == True:
    print('match')
    break
    i += 1
    else:
    print('no match')
    37 条回复    2018-05-23 05:56:50 +08:00
    ballshapesdsd
        1
    ballshapesdsd  
       2018-05-21 18:52:37 +08:00   ❤️ 1
    (''.join('1' if y else '0' for y in b)) in (''.join('1' if x else '0' for x in a))
    widewing
        2
    widewing  
       2018-05-21 18:56:15 +08:00 via Android
    [x in a for x in b]
    takato
        3
    takato  
       2018-05-21 19:08:03 +08:00   ❤️ 1
    这不就是 KMP 吗?
    Arnie97
        4
    Arnie97  
       2018-05-21 19:27:53 +08:00 via Android
    @widewing 你写的这个东西和楼主想实现的功能有任何关系么…

    >>> a = [0, 1]
    >>> b = [1, 1, 1, 1, 1]
    >>> [x in a for x in b]
    [True, True, True, True, True]
    wdc63
        5
    wdc63  
       2018-05-21 20:33:47 +08:00
    >>> from numpy import *
    >>> a = array([False, False, False, True, True, True, False, False, False, False, False, False])
    >>> b = array([True, True, True])
    >>> [ i for i in b if i not in a ]
    []
    >>> b = array([True, True, 123])
    >>> [ i for i in b if i not in a ]
    [123]

    空集为真,非空集为假
    wdc63
        6
    wdc63  
       2018-05-21 20:37:04 +08:00
    本质上还是循环,算法复杂度是没变的。
    如果你的需求是求解集合子集,那不允许出现重复元素,直接转换成 set,用 in 判断是否子集
    如果你的需求中包含了元素顺序,那就比较困难了。
    wdc63
        7
    wdc63  
       2018-05-21 20:47:27 +08:00
    @Arnie97 他写反了
    pkookp8
        8
    pkookp8  
       2018-05-21 20:50:19 +08:00 via Android
    只能拿 b 的第一个去 a 里找,找对了找 b 的下一个是不是 a 的下一个,直到 b 的结尾都匹配,则 b 在 a 中
    除了循环还能有什么办法
    ipwx
        9
    ipwx  
       2018-05-21 20:51:47 +08:00   ❤️ 1
    先引入 rolling_window: https://gist.github.com/seberg/3866040

    然后

    import numpy as np

    a = np.array([False, False, False, True, True, True, False, False, False, False, False, False])
    b = np.array([True, True, True])

    l = b.shape[0]
    needle = np.equal(rolling_window(a, l), b)
    is_matched = np.max(np.sum(needle, axis=-1)) == l
    ipwx
        10
    ipwx  
       2018-05-21 20:55:11 +08:00
    另外题主,b == a[i:i+3] 这种写法已经 deprecated 了,要用 np.equal
    roy2220
        11
    roy2220  
       2018-05-21 21:30:03 +08:00   ❤️ 1
    我来偷个懒:
    a = bytes([False, False, False, True, True, True, False, False, False, False, False, False])
    b = bytes([True, True, True])
    match = a.find(b) >= 0
    print(match)
    lyusantu
        12
    lyusantu  
       2018-05-21 21:43:03 +08:00
    那就递归吧
    Arnie97
        13
    Arnie97  
       2018-05-21 22:24:01 +08:00 via Android
    @wdc63 显然需求里包含了元素顺序,不然一共就 True 和 False 两种有啥好判断的
    songdg
        14
    songdg  
    OP
       2018-05-21 22:31:38 +08:00
    @wdc63 这个我知道,只是不想用纯 Python 写循环,又找不到 numpy 有什么函数可用。
    wdc63
        15
    wdc63  
       2018-05-21 23:11:18 +08:00
    @songdg 你的需求决定了你的算法只能是循环决定,难道有现成的 numpy 函数它运行的时候就不需要循环了吗?
    wdc63
        16
    wdc63  
       2018-05-21 23:12:03 +08:00
    @Arnie97 他自己写那段代码就没包含。
    wdc63
        17
    wdc63  
       2018-05-21 23:13:52 +08:00
    @Arnie97 你的意思如果是要打印出每一个 True False 的话那就用[x in b for x in a]
    ipwx
        18
    ipwx  
       2018-05-22 00:34:53 +08:00 via iPhone
    @songdg 不点评我那个实现吗
    ipwx
        19
    ipwx  
       2018-05-22 00:35:06 +08:00 via iPhone
    @wdc63 我那个实现就不用循环
    songdg
        20
    songdg  
    OP
       2018-05-22 00:58:17 +08:00
    @ipwx 谢谢,你那个有点复杂,一时看不懂,不好意思。
    rabbbit
        21
    rabbbit  
       2018-05-22 01:05:42 +08:00
    我想到的是''.join(map(str, b)) in ''.join(map(str, a))
    看了下评论,为什么说 1 楼的代码是错的?
    noli
        22
    noli  
       2018-05-22 04:54:38 +08:00 via iPhone
    false 为 0
    True 为 1
    bool 数组转换为整型数之后,判断以 b 为模余数是否为 0
    就可以了
    locktionc
        23
    locktionc  
       2018-05-22 07:08:02 +08:00   ❤️ 2
    楼上这这些人,你们怎么一根筋不知道变通?

    ```
    import numpy as np

    a = np.array([False, False, False, True, True, True, False, False, False, False, False, False])
    b = np.array([True, True, True])
    if str(b)[1:-1] in str(a):
    print('b 在 a 中')
    ```
    boboliu
        24
    boboliu  
       2018-05-22 07:15:41 +08:00 via Android
    @locktionc 哈哈哈,这操作很骚…
    Binb
        25
    Binb  
       2018-05-22 07:56:43 +08:00 via Android
    用字符串匹配喽
    lastpass
        26
    lastpass  
       2018-05-22 08:33:38 +08:00 via Android
    吓得我赶紧去翻了一下编译原理,这就是最简单的有穷自动机呀。
    PythonAnswer
        27
    PythonAnswer  
       2018-05-22 08:36:12 +08:00 via iPhone
    Map reduce filter
    clearCode1124
        28
    clearCode1124  
       2018-05-22 08:46:26 +08:00
    sets.difference()
    ipwx
        29
    ipwx  
       2018-05-22 09:52:15 +08:00 via iPhone
    @locktionc 如果不是 bool,这招就不管用了
    xxxy
        30
    xxxy  
       2018-05-22 10:31:34 +08:00
    楼上说了,用 kmp 可以实现
    Raymon111111
        31
    Raymon111111  
       2018-05-22 10:47:06 +08:00
    不就是最长公共子序列吗
    congeec
        32
    congeec  
       2018-05-22 10:50:55 +08:00 via iPhone
    @ipwx 老哥这些 gist 里的注释和 doc test 都是你手写的么?

    @locktionc 大胸弟你这样会被打死的
    ipwx
        33
    ipwx  
       2018-05-22 10:58:31 +08:00   ❤️ 1
    @congeec 这个 gist 不是我写的,是我见过的写得最好的 rolling_window。

    我昨天写的 np.max 其实还不太妥当。用 np.any 其实就够了:

    is_matched = np.any(np.equal(np.sum(needle, axis=-1), l).astype(np.bool))
    locktionc
        34
    locktionc  
       2018-05-22 11:07:41 +08:00
    @ipwx 也管用。
    ipwx
        35
    ipwx  
       2018-05-22 11:12:13 +08:00
    @locktionc 浮点数的话,要用 (a-b) < eps,就用不了你这方法了。

    @congeec 上面的 astype(np.bool) 似乎不必要。
    lolizeppelin
        36
    lolizeppelin  
       2018-05-22 12:16:26 +08:00 via Android
    转 set b-a
    songdg
        37
    songdg  
    OP
       2018-05-23 05:56:50 +08:00
    谢谢各位热心的 v2exer。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2711 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:39 · PVG 20:39 · LAX 04:39 · JFK 07:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.