Python 名称缩写发现
Python Name Abreviation finding
我得到的信息是这样的
xy123, xy0123, xyz_123, and xy01
XYZ
是不同的字母,123
是不同的数字。例如 QWA_0230
。有时我会收到由 _
分隔的任意数量的字母和数字。
我对一行代码很感兴趣,无论是否有 _
,它都能在开头找到字母,字母数量与它附带的字母一样多。现在,如果有 _
,我就能找到它。但如果没有,不知道该怎么办。
name="QWA_0230"
begName=name.split("_")[0]
#begName=QWA
#name2="QW0210"
#want the same code to work with this kind of name
我想我需要一个 if 语句来查找是否存在 _
if true 运行 我得到的。如果为假 运行 当字母停止和数字开始时可以破译的其他东西。
您可以使用 itertools.takewhile,获取第一个非字母字符之前的字符。
from itertools import takewhile
name = "QWA_0230"
beg_name = "".join(takewhile(str.isalpha,name))
print(beg_name)
QWA
name2 = "QW0210"
beg_name = "".join(takewhile(str.isalpha,name2))
print(beg_name)
QW
对于数字,您可以使用itertools.dropwhile
:
name2="QW0210"
print("".join(dropwhile(lambda x: not x.isdigit(),name2)))
或者您可以在循环中使用 isalpha
或 isdigit
:
print("".join(x for x in name if x.isalpha()))
print("".join(x for x in name if x.isdigit())
如果速度是个问题,这将胜过任何其他选项:
a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
In [8]: %%timeit
res = expr.search("QWA_0230").groups()
a,b = res[0],res[-1]
...:
1000000 loops, best of 3: 830 ns per loop
In [9]: timeit a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
1000000 loops, best of 3: 510 ns per loop
In [17]: a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
In [18]: a
Out[18]: '0230'
In [19]: b
Out[19]: 'QWA
您也可以使用正则表达式来做到这一点:
import re
expr = re.compile("([a-z]+)(_?)([0-9]+)", re.I) # case insensitive
expr.search("QWA_0230").groups()
# ('QWA', '_', '0230')
expr.search("xy123").groups()
# ('xy', None, '123')
如果有既没有数字也没有字母的数据,您需要检查返回的搜索 none:
result = expr.search("xy123")
if not result:
return (None,None,None)
return result.groups()
字母总是分组[0],数字总是分组[-1]
我得到的信息是这样的
xy123, xy0123, xyz_123, and xy01
XYZ
是不同的字母,123
是不同的数字。例如 QWA_0230
。有时我会收到由 _
分隔的任意数量的字母和数字。
我对一行代码很感兴趣,无论是否有 _
,它都能在开头找到字母,字母数量与它附带的字母一样多。现在,如果有 _
,我就能找到它。但如果没有,不知道该怎么办。
name="QWA_0230"
begName=name.split("_")[0]
#begName=QWA
#name2="QW0210"
#want the same code to work with this kind of name
我想我需要一个 if 语句来查找是否存在 _
if true 运行 我得到的。如果为假 运行 当字母停止和数字开始时可以破译的其他东西。
您可以使用 itertools.takewhile,获取第一个非字母字符之前的字符。
from itertools import takewhile
name = "QWA_0230"
beg_name = "".join(takewhile(str.isalpha,name))
print(beg_name)
QWA
name2 = "QW0210"
beg_name = "".join(takewhile(str.isalpha,name2))
print(beg_name)
QW
对于数字,您可以使用itertools.dropwhile
:
name2="QW0210"
print("".join(dropwhile(lambda x: not x.isdigit(),name2)))
或者您可以在循环中使用 isalpha
或 isdigit
:
print("".join(x for x in name if x.isalpha()))
print("".join(x for x in name if x.isdigit())
如果速度是个问题,这将胜过任何其他选项:
a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
In [8]: %%timeit
res = expr.search("QWA_0230").groups()
a,b = res[0],res[-1]
...:
1000000 loops, best of 3: 830 ns per loop
In [9]: timeit a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
1000000 loops, best of 3: 510 ns per loop
In [17]: a,b = name.translate(None,"ABCDEFGHIJKLMNOPQRSTUVWXWY_"),name.translate(None,"1234567890_")
In [18]: a
Out[18]: '0230'
In [19]: b
Out[19]: 'QWA
您也可以使用正则表达式来做到这一点:
import re
expr = re.compile("([a-z]+)(_?)([0-9]+)", re.I) # case insensitive
expr.search("QWA_0230").groups()
# ('QWA', '_', '0230')
expr.search("xy123").groups()
# ('xy', None, '123')
如果有既没有数字也没有字母的数据,您需要检查返回的搜索 none:
result = expr.search("xy123")
if not result:
return (None,None,None)
return result.groups()
字母总是分组[0],数字总是分组[-1]