如何重写字符串的遍历方法? - 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
Morriaty
V2EX    Python

如何重写字符串的遍历方法?

  •  
  •   Morriaty 2018 年 6 月 14 日 4933 次点击
    这是一个创建于 2828 天前的主题,其中的信息可能已经有所发展或是发生改变。

    默认的遍历方式是

    for i in "为了让大家在 V2EX 上的时间更有效率": yield i ['为', '了', '让', '大', '家', '在', ' ', 'V', '2', 'E', 'X', ' ', '上', '的', '时', '间', '更', '有', '效', '率'] 

    但现在希望的方式是遇见连续的英文数字就合并

    for i in "为了让大家在 V2EX 上的时间更有效率": yield i ['为', '了', '让', '大', '家', '在', ' ', 'V2EX', ' ', '上', '的', '时', '间', '更', '有', '效', '率'] 

    当然,最简单的方式是写一个foreach函数,然后for i in foreach(string)

    只是想确认下是否可以直接重写字符串的遍历方法

    第 1 条附言    2018 年 6 月 15 日

    貌似我表述的不够清楚,我不是不会写这个遍历函数,我是想重写str的__iter__方法,但不知道具体怎么做,大致逻辑入下

    import builtins class MyStr(str): def __iter__(self): # 不知道怎么改 pass builtins.str = MyStr a = "测试Test test123结束" for i in a: print i ###预期输出 测 试 Test test123 结 束 
    21 条回复    2018-06-15 16:39:14 +08:00
    shuianfendi6
        1
    shuianfendi6  
       2018 年 6 月 14 日
    re.compile("[a-zA-Z0-9]+|[^\x00-\xff]").findall(a)
    changrui0608
        2
    changrui0608  
       2018 年 6 月 14 日
    感觉可以自定义一个类继承 str,然后自己重写相应的方法
    https://stackoverflow.com/questions/2673651/inheritance-from-str-or-int
    F1024
        3
    F1024  
       2018 年 6 月 14 日
    "为了让大家在 V2EX 上的时间更有效率".split("")
    linxiaoziruo
        4
    linxiaoziruo  
       2018 年 6 月 14 日
    题主头像是谁
    wangyongbo
        5
    wangyongbo  
       2018 年 6 月 14 日
    for x in re.findall('[^A-Za-z\d]{1}|[A-Za-z\d]+', s):
    ... print x
    crb912
        6
    crb912  
       2018 年 6 月 14 日 via Android
    Cpython 的字符串遍历,默认用了 yield 关键字?
    polythene
        7
    polythene  
       2018 年 6 月 14 日
    @crb912 好像是用了 iterator 协议
    crb912
        8
    crb912  
       2018 年 6 月 14 日 via Android
    @polythene yield 关键字,会让函数成为生成器 generator。
    不同点是,1. 生成器只能被迭代一次,迭代器 iterator 没有这种限制,2. 而且生成器的元素不会一次读入内存,而是会在调用逐个加载。它们的共同点都实现了可迭代协议__iter__方法,__next__方法。
    所以 yield 应该是你随手写的吧?
    ccsiyu
        9
    ccsiyu  
       2018 年 6 月 14 日
    写一个两层循环,在内层循环里用贪心法向前搜索能合并的单词

    实际上还是 O(n)
    Morriaty
        10
    Morriaty  
    OP
       2018 年 6 月 14 日
    @changrui0608 是不是我表述的太差了,貌似只有你一个人理解了我的意思
    不过 SO 这个依然很麻烦,我必须修改所有的 str 赋值语句
    a = "xxx"
    改成
    a = MyStr("xxx")
    Morriaty
        11
    Morriaty  
    OP
       2018 年 6 月 15 日
    @linxiaoziruo 长泽雅美
    Morriaty
        12
    Morriaty  
    OP
       2018 年 6 月 15 日
    @shuianfendi6 @wangyongbo @ccsiyu 你们误会我意思了,详见 append
    ccsiyu
        13
    ccsiyu  
       2018 年 6 月 15 日
    @Morriaty 知道了,你知道算法,但是想 override 原来的方法。那就用一个子类继承 str 这个父类(不熟悉 python,根据上下文猜测的)然后 override 就行了
    XYxe
        14
    XYxe  
       2018 年 6 月 15 日
    ```python
    import cffi
    import ctypes


    class new_str_iterator():
    def __init__(self, s):
    self.index = 0
    self.s = s

    def __iter__(self):
    return self

    def __next__(self):
    '''你需要的功能'''


    def __new_str_iter__(obj_addr):
    obj = ctypes.cast(obj_addr, ctypes.py_object).value
    iter_obj = new_str_iterator(obj)
    ctypes.pythonapi.Py_IncRef(id(iter_obj))
    return id(iter_obj)


    ctypes.pythonapi.Py_IncRef.argtypes = [ctypes.c_size_t]
    ITER_FUNC = ctypes.CFUNCTYPE(ctypes.c_ssize_t, ctypes.c_ssize_t)
    cnew_str_iter = ITER_FUNC(__new_str_iter__)

    ffi = cffi.FFI()
    tp_iter_pointer = ffi.cast("size_t *", id(str) + 216)
    tp_iter_pointer[0] = ctypes.cast(cnew_str_iter, ctypes.c_void_p).value
    ```
    XYxe
        15
    XYxe  
       2018 年 6 月 15 日   1
    xiaket
        16
    xiaket  
       2018 年 6 月 15 日
    根据 import this, 这种 magic 东西最好是显式的而不是隐式的, 所以推荐显式地定义 /import 一个类, 然后将你的逻辑放到这个类里面.
    v2gba
        17
    v2gba   div class="badges">   2018 年 6 月 15 日
    class Vstr(str):
    def __iter__(self):
    special_set = 'abcdefghijklmnV2EX'
    special_str = ''
    for i in super().__iter__():
    if i in special_set:
    special_str += i
    else:
    if special_str:
    yield special_str
    special_str = ''
    yield i


    mystr = Vstr('为了让 abc 在 V2EX 上的 egg222 时间更有效率')
    for i in mystr:
    print(i)
    araraloren
        18
    araraloren  
       2018 年 6 月 15 日
    不是可以用 wrapper/decorator/装饰器么,获取原函数的返回值,自己处理然后返回,同#17

    #!/usr/bin/perl6
    # your code goes here

    Str.^find_method("split").wrap(
    ----sub split(|c) {
    --------my @x = callwith(|c); # call Str::split with all arguments
    --------my @r = [];
    --------my ($i, $j) = (0, 0);
    --------my regex letter-number { <[a..z0..9]> }

    --------for @x -> $x {
    ------------if $x.lc ~~ /<letter-number>/ && $i > 0 && @r[$i-1].lc ~~ /<letter-number>/ {
    ----------------@r[$i-1] ~= $x;
    ------------} else {
    ----------------@r[$i++] = $x;
    ------------}
    --------}
    --------@r;
    ----}
    );

    my $ms = "为了让大家在 V2EX 上的时间更有效率";

    say $ms;

    say $ms.split("").join("===");

    https://ideone.com/FLlxXe
    HaoC12
        19
    HaoC12  
       2018 年 6 月 15 日
    是不是可以通过栈来实现,判断进入的元素是不是字母,如果是在判断下一个,直到不是字母,出栈,下一个元素入栈。
    excellentcx
        20
    excellentcx  
       2018 年 6 月 15 日
    难道不是正则表达式就可以完成的么???
    darkjoker
        21
    darkjoker  
       2018 年 6 月 15 日
    @linxiaoziruo Masami 麻酱~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1352 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 92ms UTC 17:40 PVG 01:40 LAX 10:40 JFK 13:40
    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