Có thể phân tách một chuỗi mỗi ký tự thứ n?
Ví dụ: giả sử tôi có một chuỗi chứa như sau:
'1234567890'
Làm thế nào tôi có thể làm cho nó trông như thế này:
['12','34','56','78','90']
Có thể phân tách một chuỗi mỗi ký tự thứ n?
Ví dụ: giả sử tôi có một chuỗi chứa như sau:
'1234567890'
Làm thế nào tôi có thể làm cho nó trông như thế này:
['12','34','56','78','90']
Câu trả lời:
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']
Chỉ cần hoàn thành, bạn có thể làm điều này với biểu thức chính quy:
>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']
Đối với số lượng ký tự lẻ bạn có thể làm điều này:
>>> import re
>>> re.findall('..?', '123456789')
['12', '34', '56', '78', '9']
Bạn cũng có thể làm như sau, để đơn giản hóa regex cho các đoạn dài hơn:
>>> import re
>>> re.findall('.{1,2}', '123456789')
['12', '34', '56', '78', '9']
Và bạn có thể sử dụng re.finditer
nếu chuỗi dài để tạo chunk bằng chunk.
'.'*n
để làm cho nó rõ ràng hơn. Không tham gia, không nén, không vòng lặp, không hiểu danh sách; chỉ cần tìm hai nhân vật tiếp theo cạnh nhau, đó chính xác là cách bộ não con người nghĩ về nó. Nếu Monty Python vẫn còn sống, anh ấy sẽ thích phương pháp này!
flags=re.S
.
Đã có một chức năng sẵn có trong python cho việc này.
>>> from textwrap import wrap
>>> s = '1234567890'
>>> wrap(s, 2)
['12', '34', '56', '78', '90']
Đây là những gì các chuỗi để bọc nói:
>>> help(wrap)
'''
Help on function wrap in module textwrap:
wrap(text, width=70, **kwargs)
Wrap a single paragraph of text, returning a list of wrapped lines.
Reformat the single paragraph in 'text' so it fits in lines of no
more than 'width' columns, and return a list of wrapped lines. By
default, tabs in 'text' are expanded with string.expandtabs(), and
all other whitespace characters (including newline) are converted to
space. See TextWrapper class for available keyword args to customize
wrapping behaviour.
'''
wrap
có thể không trả về những gì được yêu cầu nếu chuỗi chứa khoảng trắng. ví dụ wrap('0 1 2 3 4 5', 2)
trả về ['0', '1', '2', '3', '4', '5']
(các phần tử bị tước)
Một cách phổ biến khác để nhóm các yếu tố thành các nhóm có độ dài n:
>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']
Phương pháp này xuất phát trực tiếp từ các tài liệu cho zip()
.
zip(*[iter(s)]*2)
khó hiểu, hãy đọc Làm thế nào để zip(*[iter(s)]*n)
làm việc trong Python? .
>>> map(''.join, zip(*[iter('01234567')]*5))
->['01234']
zip()
bằng itertools.zip_longest()
:map(''.join, zip_longest(*[iter(s)]*2, fillvalue=''))
Tôi nghĩ rằng nó ngắn hơn và dễ đọc hơn phiên bản itertools:
def split_by_n(seq, n):
'''A generator to divide a sequence into chunks of n units.'''
while seq:
yield seq[:n]
seq = seq[n:]
print(list(split_by_n('1234567890', 2)))
Sử dụng nhiều itertools từ PyPI:
>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']
Bạn có thể sử dụng grouper()
công thức từ itertools
:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
Các chức năng này là bộ nhớ hiệu quả và làm việc với bất kỳ iterables nào.
Hãy thử đoạn mã sau:
from itertools import islice
def split_every(n, iterable):
i = iter(iterable)
piece = list(islice(i, n))
while piece:
yield piece
piece = list(islice(i, n))
s = '1234567890'
print list(split_every(2, list(s)))
yield ''.join(piece)
để làm cho nó hoạt động như mong đợi: eval.in/813878
>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x)]
['12', '34', '56', '78', '90']
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
['123', '456', '789']
Thử cái này:
s='1234567890'
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])
Đầu ra:
['12', '34', '56', '78', '90']
Như mọi khi, cho những người yêu thích một lớp lót
n = 2
line = "this is a line split into n characters"
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
print(line)
tôi nhận được this is a line split into n characters
. Bạn có thể tốt hơn đặt : line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
? Khắc phục điều này và đó là một câu trả lời tốt :).
,blah
và tại sao nó cần thiết? Tôi nhận thấy tôi có thể thay thế blah
bằng bất kỳ ký tự alpha nào, nhưng không phải số và không thể xóa blah
hoặc / và dấu phẩy. Trình chỉnh sửa của tôi đề nghị thêm khoảng trắng sau ,
: s
enumerate
trả về hai lần lặp, vì vậy bạn cần hai nơi để đặt chúng. Nhưng bạn không thực sự cần lần lặp thứ hai cho bất cứ điều gì trong trường hợp này.
blah
tôi thích sử dụng dấu gạch dưới hoặc dấu gạch dưới gấp đôi, hãy xem: stackoverflow.com/questions/5893163/ Kẻ
Một giải pháp đệ quy đơn giản cho chuỗi ngắn:
def split(s, n):
if len(s) < n:
return []
else:
return [s[:n]] + split(s[n:], n)
print(split('1234567890', 2))
Hoặc ở dạng như vậy:
def split(s, n):
if len(s) < n:
return []
elif len(s) == n:
return [s]
else:
return split(s[:n], n) + split(s[n:], n)
, minh họa mô hình phân chia và chinh phục điển hình theo cách tiếp cận đệ quy rõ ràng hơn (mặc dù thực tế không cần thiết phải làm theo cách này)
more_itertools.sliced
đã được đề cập trước đó. Dưới đây là bốn tùy chọn khác từ more_itertools
thư viện:
s = "1234567890"
["".join(c) for c in mit.grouper(2, s)]
["".join(c) for c in mit.chunked(s, 2)]
["".join(c) for c in mit.windowed(s, 2, step=2)]
["".join(c) for c in mit.split_after(s, lambda x: int(x) % 2 == 0)]
Mỗi tùy chọn sau tạo ra đầu ra sau:
['12', '34', '56', '78', '90']
Tài liệu cho các tùy chọn thảo luận: grouper
, chunked
, windowed
,split_after
Điều này có thể đạt được bằng một vòng lặp đơn giản.
a = '1234567890a'
result = []
for i in range(0, len(a), 2):
result.append(a[i : i + 2])
print(result)
Đầu ra trông giống như ['12', '34', '56', '78', '90', 'a']