python数字转字符串固定位数_python-将String转换为64位整
数映射字符以⾃定...
您将4个不同“数字”的字符串解释为数字,因此以4为基数.如果您有⼀串实际数字,范围为0-3,则可以让int()真正快速地⽣成⼀个整数.
def seq_to_int(seq, _m=str.maketrans('ACGT', '0123')):
return anslate(_m), 4)
上⾯的函数使⽤anslate()⽤匹配的数字替换4个字符中的每个字符(我使⽤静态str.maketrans() function创建转换表).然后将所得的数字字符串解释为以4为底的整数.
请注意,这将⽣成⼀个整数对象,⽽不是零和⼀个字符的⼆进制字符串:
>>> seq_to_int('TGTGAGAAGCACCATAAAAGGCGTTGTG')
67026852874722286
>>> format(seq_to_int('TGTGAGAAGCACCATAAAAGGCGTTGTG'), '016x')
'00ee20914c029bee'
>>> format(seq_to_int('TGTGAGAAGCACCATAAAAGGCGTTGTG'), '064b')
python格式化输出format'0000000011101110001000001001000101001100000000101001101111101110'
这⾥不需要填充;只要您的输⼊序列为32个字母或更少,则结果整数将适合⽆符号8字节整数表⽰形式.在上⾯的输出⽰例中,我使⽤format()字符串分别将该整数值格式化为⼗六进制和⼆进制字符串,然后将这些表⽰形式零填充到64位数字的正确位数.
为了衡量这是否更快,让我们随机抽取⼀百万个测试字符串(每个字符串长28个字符):
>>> from random import choice
>>> testvalues = [''.join([choice('ATCG') for _ in range(28)]) for _ in range(10 ** 6)]
在使⽤2.9 GHz Intel Core i7的Macbook Pro和Python 3.6.5上,上述功能可以在3/4秒内产⽣100万次转换:
>>> from timeit import timeit
>>> timeit('seq_to_int(next(tviter))', 'from __main__ import testvalues, seq_to_int; tviter=iter(testvalues)')
0.7316284350017668
因此,每个通话为0.73微秒.
(以前,我提倡使⽤预计算版本,但经过试验,我采⽤了以4为底的想法).
要将其与到⽬前为⽌发布的其他⽅法进⾏⽐较,还需要调整⼀些⽅法以产⽣整数,并将其包装到函数中:
def seq_to_int_alexhall_a(seq, mapping={'A': b'00', 'C': b'01', 'G': b'10', 'T': b'11'}):
return int(b''.join(map(mapping.__getitem__, seq)), 2)
def seq_to_int_alexhall_b(seq, mapping={'A': b'00', 'C': b'01', 'G': b'10', 'T': b'11'}):
return int(b''.join([mapping[c] for c in seq]), 2)
def seq_to_int_jonathan_may(seq, mapping={'A': 0b00, 'C': 0b01, 'G': 0b10, 'T': 0b11}):
result = 0
for char in seq:
result = result << 2
result = result | mapping[char]
return result
然后我们可以⽐较这些:
>>> testfunctions = {
... 'Alex Hall (A)': seq_to_int_alexhall_a,
... 'Alex Hall (B)': seq_to_int_alexhall_b,
... 'Jonathan May': seq_to_int_jonathan_may,
... 'martineau': base_decode,
.
.. 'Martijn Pieters': seq_to_int,
... }
>>> setup = """\n... from __main__ import testvalues, {} as testfunction ... tviter = iter(testvalues)
... """
>>> for name, f in testfunctions.items():
... res = timeit('testfunction(next(tviter))', setup.format(f.__name__)) ... print(f'{name:>15}: {res:8.5f}')
...
Alex Hall (A): 2.17879
Alex Hall (B): 2.40771
Jonathan May: 3.30303
martineau: 16.60615
Martijn Pieters: 0.73452
我提出的以4为基的⽅法很容易赢得这⼀⽐较.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。