#python #list #binary
Вопрос:
У меня есть двоичная строка типа '1100011101'
. Я хотел бы проанализировать его в виде списка, где каждый фрагмент 1 или 0 является отдельным значением в списке.
Такие как: '1100011101'
становится ['11', '000', '111', '0', '1']
Ответ №1:
Вы можете извлечь из этого (незначительную) часть производительности, используя регулярное выражение вместо groupby()
join()
. Это просто находит группы 1
или 0
:
import re
s = '1100011101'
l = re.findall(r"0 |1 ", s)
# ['11', '000', '111', '0', '1']
Тайминги:
s = '1100011101' * 1000
%timeit l = [''.join(g) for _, g in groupby(s)]
# 1.16 ms ± 9.79 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit re.findall(r"0 |1 ", s)
# 723 µs ± 5.32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Ответ №2:
Воспользуйся itertools.groupby
:
from itertools import groupby
binary = "1100011101"
result = ["".join(repeat) for _, repeat in groupby(binary)]
print(result)
Выход
['11', '000', '111', '0', '1']
Ответ №3:
Вставьте пробел между переходами 01 и 10 с помощью .replace (), а затем разделите полученную строку:
'1100011101'.replace("01","0 1").replace("10","1 0").split()
['11', '000', '111', '0', '1']
Ответ №4:
с groupby
>>> from itertools import groupby as f
>>> x = str(1100011101)
>>> sol = [''.join(v) for k, v in f(x)]
>>> print(sol)
['11', '000', '111', '0', '1']
без использования groupby
и если вы хотите более быстрого выполнения
def func(string):
if not string:
return []
def get_data(string):
if not string:
return
count = 0
target = string[0]
for i in string:
if i==target:
count =1
else:
yield target*count
count = 1
target = i
if count>0:
yield target*count
return list(get_data(string))
x = '1100011101'
sol =func(x)
print(sol)
выход
['11', '000', '111', '0', '1']
Тайминги на моей машине
from itertools import groupby
s = '11000111010101' * 100000
%timeit l = [''.join(g) for _, g in groupby(s)]
318 ms ± 2.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
import re
s = '11000111010101' * 100000
%timeit l = re.findall(r"0 |1 ", s)
216 ms ± 2.01 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
def func(string):
if not string:
return []
def get_data(string):
if not string:
return
count = 0
target = string[0]
for i in string:
if i==target:
count =1
else:
yield target*count
count = 1
target = i
if count>0:
yield target*count
return list(get_data(string))
s = '11000111010101' * 100000
%timeit func(s)
205 ms ± 11.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
####################################################################
from itertools import groupby
s = '11000111010101' * 1000
%timeit l = [''.join(g) for _, g in groupby(s)]
3.28 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
import re
s = '11000111010101' * 1000
%timeit l = re.findall(r"0 |1 ", s)
2.06 ms ± 57.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
def func(string):
if not string:
return []
def get_data(string):
if not string:
return
count = 0
target = string[0]
for i in string:
if i==target:
count =1
else:
yield target*count
count = 1
target = i
if count>0:
yield target*count
return list(get_data(string))
s = '11000111010101' * 1000
%timeit func(s)
1.91 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)