默认的遍历方式是
for i in "为了让大家在 V2EX 上的时间更有效率":
yield i
['为', '了', '让', '大', '家', '在', ' ', 'V', '2', 'E', 'X', ' ', '上', '的', '时', '间', '更', '有', '效', '率']
但现在希望的方式是遇见连续的英文数字就合并
for i in "为了让大家在 V2EX 上的时间更有效率":
yield i
['为', '了', '让', '大', '家', '在', ' ', 'V2EX', ' ', '上', '的', '时', '间', '更', '有', '效', '率']
当然,最简单的方式是写一个foreach
函数,然后for i in foreach(string)
只是想确认下是否可以直接重写字符串的遍历方法
貌似我表述的不够清楚,我不是不会写这个遍历函数,我是想重写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
结
束
1
shuianfendi6 2018-06-14 15:50:55 +08:00
re.compile("[a-zA-Z0-9]+|[^\x00-\xff]").findall(a)
|
2
changrui0608 2018-06-14 18:50:19 +08:00
感觉可以自定义一个类继承 str,然后自己重写相应的方法
https://stackoverflow.com/questions/2673651/inheritance-from-str-or-int |
3
F1024 2018-06-14 19:06:08 +08:00
"为了让大家在 V2EX 上的时间更有效率".split("")
|
4
linxiaoziruo 2018-06-14 19:44:53 +08:00
题主头像是谁
|
5
wangyongbo 2018-06-14 20:04:32 +08:00
for x in re.findall('[^A-Za-z\d]{1}|[A-Za-z\d]+', s):
... print x |
6
crb912 2018-06-14 20:52:58 +08:00 via Android
Cpython 的字符串遍历,默认用了 yield 关键字?
|
8
crb912 2018-06-14 21:39:16 +08:00 via Android
@polythene yield 关键字,会让函数成为生成器 generator。
不同点是,1. 生成器只能被迭代一次,迭代器 iterator 没有这种限制,2. 而且生成器的元素不会一次读入内存,而是会在调用逐个加载。它们的共同点都实现了可迭代协议__iter__方法,__next__方法。 所以 yield 应该是你随手写的吧? |
9
ccsiyu 2018-06-14 22:35:42 +08:00
写一个两层循环,在内层循环里用贪心法向前搜索能合并的单词
实际上还是 O(n) |
10
Morriaty OP |
11
Morriaty OP @linxiaoziruo 长泽雅美
|
12
Morriaty OP |
13
ccsiyu 2018-06-15 02:10:00 +08:00
@Morriaty 知道了,你知道算法,但是想 override 原来的方法。那就用一个子类继承 str 这个父类(不熟悉 python,根据上下文猜测的)然后 override 就行了
|
14
XYxe 2018-06-15 03:08:48 +08:00
```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 ``` |
15
XYxe 2018-06-15 03:13:50 +08:00 1
|
16
xiaket 2018-06-15 07:12:16 +08:00
根据 import this, 这种 magic 东西最好是显式的而不是隐式的, 所以推荐显式地定义 /import 一个类, 然后将你的逻辑放到这个类里面.
|
17
MrGba2z 2018-06-15 08:21:48 +08:00
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) |
18
araraloren 2018-06-15 09:16:18 +08:00
不是可以用 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 |
19
HaoC12 2018-06-15 10:54:55 +08:00
是不是可以通过栈来实现,判断进入的元素是不是字母,如果是在判断下一个,直到不是字母,出栈,下一个元素入栈。
|
20
excellentcx 2018-06-15 16:20:49 +08:00
难道不是正则表达式就可以完成的么???
|
21
darkjoker 2018-06-15 16:39:14 +08:00
@linxiaoziruo Masami 麻酱~
|