2011-01-03 47 views
22

Con trăn có tích hợp (có nghĩa là trong các thư viện chuẩn) để thực hiện chia tách các chuỗi tạo ra một trình lặp hơn là một danh sách không? Tôi có trong tâm trí làm việc trên dây rất dài và không cần phải tiêu thụ hầu hết các chuỗi.Tách một chuỗi thành một bộ lặp

+2

"không cần thiết để tiêu thụ phần lớn chuỗi"? Điều đó có nghĩa là gì? Đối tượng chuỗi là tất cả trong bộ nhớ, phải không? Vì nó là tất cả trong bộ nhớ, và nó đã là một chuỗi, không có gì cần thiết để lặp qua các ký tự. Bạn có thể vui lòng xác định ý của bạn bằng "không cần thiết để tiêu thụ hầu hết chuỗi" không? –

+0

Có, chuỗi đã có trong bộ nhớ. Nhưng tôi không cần phải đi qua toàn bộ chuỗi để tìm ra nơi để chia tách hoặc để tạo ra các chất nền kết quả từ sự phân chia. –

+1

Có lẽ bạn cần một tokeniser hoặc máy quét của một số loại mà cung cấp một iterator. Câu trả lời dưới đây với giải pháp biểu thức chính quy có thể hoạt động. –

Trả lời

15

Không tách chuỗi trực tiếp như vậy, nhưng mô-đun rere.finditer() (và tương ứng finditer() phương pháp trên bất kỳ cụm từ thông dụng được biên dịch nào).

@Zero hỏi cho một ví dụ:

>>> import re 
>>> s = "The quick brown\nfox" 
>>> for m in re.finditer('\S+', s): 
...  print(m.span(), m.group(0)) 
... 
(0, 3) The 
(4, 9) quick 
(13, 18) brown 
(19, 22) fox 
+2

Một ví dụ về cách sử dụng 're.finditer()' để lặp các chuỗi phân chia sẽ hữu ích. – Zero

+1

@ Zero, không chính xác lắm, nhưng ở đây bạn đi. – Duncan

5

Giống như S. Lott, tôi hoàn toàn không biết những gì bạn muốn. Đây là mã có thể giúp:

s = "This is a string." 
for character in s: 
    print character 
for word in s.split(' '): 
    print word 

Ngoài ra còn có s.index() và s.find() để tìm ký tự tiếp theo.


Sau đó: Ok, một cái gì đó như thế này.

>>> def tokenizer(s, c): 
...  i = 0 
...  while True: 
...   try: 
...    j = s.index(c, i) 
...   except ValueError: 
...    yield s[i:] 
...    return 
...   yield s[i:j] 
...   i = j + 1 
... 
>>> for w in tokenizer(s, ' '): 
...  print w 
... 
This 
is 
a 
string. 
+1

Xem làm rõ trong các ý kiến. Điều này không trả lời câu hỏi. – marcog

+0

Anh ấy cũng yêu cầu một cách rõ ràng * được xây dựng trong * –

+3

@ 7vies: Tôi nghĩ điều này tốt hơn là nói "Không" hoặc nói "Sử dụng cụm từ thông dụng (tức là câu trả lời ở trên)". – hughdbrown

0

Bạn có thể sử dụng giống như SPARK (đã được hấp thụ vào phân phối Python bản thân, mặc dù không thể nhập cảng từ thư viện tiêu chuẩn), nhưng cuối cùng nó sử dụng biểu thức thông thường cũng vì vậy Duncan's answer có thể sẽ phục vụ quý khách chỉ cần cũng nếu nó dễ dàng như chỉ "chia nhỏ trên khoảng trắng".

Tùy chọn khác, khó khăn hơn nhiều là viết mô-đun Python của riêng bạn trong C để thực hiện nếu bạn thực sự muốn tốc độ, nhưng đó là thời gian đầu tư lớn hơn nhiều.

3

Nếu bạn không cần phải tiêu thụ toàn bộ chuỗi, đó là bởi vì bạn đang tìm kiếm một cái gì đó cụ thể, phải không? Sau đó, chỉ cần tìm điều đó, với re hoặc .find() thay vì tách. Bằng cách đó bạn có thể tìm thấy một phần của chuỗi mà bạn quan tâm và tách nó ra.

+0

Trong ứng dụng tôi đã nghĩ, tôi muốn chia nhỏ khoảng trắng, kiểm tra chuỗi con thứ ba, tùy thuộc vào thứ gì, kiểm tra chuỗi con thứ tư hoặc thứ sáu, và sau đó có thể xử lý phần còn lại của chuỗi. –

+2

ẩn dụ @pythonic: Vâng, nếu chuỗi đó là * thực sự * dài bạn có thể muốn sử dụng 're' hoặc' find'. Trong trường hợp khác, chỉ cần phân chia nó trên khoảng trắng. Tôi không biết, nhưng với tôi câu hỏi của bạn có vẻ như nó có thể được tối ưu hóa sớm. ;) Vì vậy, bạn phải cấu hình nó để chắc chắn. –

+3

ẩn dụ @pythonic: Đối với văn bản bình thường chỉ là tối ưu hóa sớm. Văn bản bắt đầu là "lớn" ở đâu đó >> 10MB. Đối với ứng dụng bạn mô tả tôi chỉ cần đi với 'text.split (None, 6)' để có được 6 từ đầu tiên. Nếu bạn phải chia toàn bộ văn bản anyways chỉ cần làm điều đó ngay lập tức. –

0

Nhìn vào itertools. Nó chứa những thứ như takewhile, islicegroupby cho phép bạn cắt một vòng lặp - một chuỗi có thể lặp lại - thành một biến thể khác dựa trên các chỉ mục hoặc một điều kiện boolean của các loại.

0

Không có tích hợp dựa trên bộ lặp tương tự của str.split. Tùy thuộc vào nhu cầu của bạn, bạn có thể tạo ra một danh sách iterator:

iterator = iter("abcdcba".split("b")) 
iterator 
# <list_iterator at 0x49159b0> 
next(iterator) 
# 'a' 

Tuy nhiên, một công cụ từ thư viện của bên thứ ba này có khả năng cung cấp những gì bạn muốn, more_itertools.split_at. Xem thêm this post để biết ví dụ.

Các vấn đề liên quan