2015-06-04 20 views
7

Tôi vẫn đang học Python, và tôi có một câu hỏi mà tôi chưa thể giải quyết được. Tôi có một chuỗi rất dài (hàng triệu dòng dài) mà tôi muốn được chia thành một chuỗi dài hơn dựa trên số lần xuất hiện cụ thể của một dấu phân cách.Python - Tách chuỗi lớn theo số lần xuất hiện dấu phân tách

Ví dụ:

ABCDEF 
// 
GHIJKLMN 
// 
OPQ 
// 
RSTLN 
// 
OPQR 
// 
STUVW 
// 
XYZ 
// 

Trong trường hợp này tôi muốn chia nhỏ dựa trên "//" và trả về một chuỗi của tất cả các dòng trước sự xuất hiện thứ n của delimeter.

Vì vậy, một đầu vào của việc tách chuỗi bằng // 1 sẽ trở lại:

ABCDEF 

một đầu vào của việc tách chuỗi bằng // 2 sẽ quay trở lại:

ABCDEF 
// 
GHIJKLMN 

một đầu vào của chia chuỗi theo // bởi 3 sẽ trả về:

ABCDEF 
// 
GHIJKLMN 
// 
OPQ 

Và cứ như vậy ... Tuy nhiên, Độ dài của chuỗi 2 triệu dòng ban đầu dường như là một vấn đề khi tôi chỉ cố gắng chia toàn bộ chuỗi và "//" và chỉ làm việc với các chỉ mục riêng lẻ. (Tôi đã nhận được một lỗi bộ nhớ) Có lẽ Python không thể xử lý rất nhiều dòng trong một phân chia? Vì vậy, tôi không thể làm điều đó.

Tôi đang tìm cách mà tôi không cần chia toàn bộ chuỗi thành hàng trăm nghìn chỉ mục khi tôi chỉ cần 100, nhưng thay vì chỉ bắt đầu từ đầu cho đến một điểm nhất định, hãy dừng và quay lại tất cả mọi thứ trước đó, mà tôi cho rằng cũng có thể nhanh hơn? Tôi hy vọng câu hỏi của tôi càng rõ ràng càng tốt.

Có cách nào đơn giản hay thanh lịch để đạt được điều này? Cảm ơn!

+2

Tại sao bạn không sử dụng trình tạo để đọc n mục đầu tiên cho đến khi bạn đọc số dấu phân cách "//" được yêu cầu? theo cách đó, bạn chỉ đọc những gì bạn cần –

+0

Cảm ơn, tôi cũng sẽ xem xét các máy phát điện vì tôi không quen với chúng. – Indie

+0

Vui lòng hiển thị mã bạn đã thử cho đến thời điểm này. –

Trả lời

1

Nếu bạn muốn làm việc với tệp thay vì chuỗi trong bộ nhớ, đây là một câu trả lời khác.

Phiên bản này được viết dưới dạng hàm đọc dòng và ngay lập tức in ra cho đến khi tìm thấy số lượng dấu phân cách được chỉ định (không cần thêm bộ nhớ để lưu toàn bộ chuỗi).

def file_split(file_name, delimiter, n=1): 
    with open(file_name) as fh: 
     for line in fh: 
      line = line.rstrip() # use .rstrip("\n") to only strip newlines 
      if line == delimiter: 
       n -= 1 
       if n <= 0: 
        return 
      print line 

file_split('data.txt', '//', 3) 

Bạn có thể sử dụng để viết các đầu ra vào một tập tin mới như thế này:

python split.py > newfile.txt 

Với việc thêm chút, bạn có thể sử dụng argparse để truyền tham số cho chương trình.

+0

Điều này thực sự hoạt động hoàn hảo và không có vấn đề gì khi xử lý tệp 2 triệu dòng. Cảm ơn bạn! – Indie

0

Ví dụ:

i = 0 
    s = "" 
    fd = open("...") 
    for l in fd: 
     if l[:-1] == delimiter: # skip last '\n' 
      i += 1 
     if i >= max_split: 
      break 
     s += l 
    fd.close() 
0

Là một cách hiệu quả hơn, bạn có thể đọc các linh sam N dòng phân cách bằng dấu phân cách của bạn vì vậy nếu bạn chắc chắn rằng tất cả các dòng của bạn được tách ra bởi delimiter bạn có thể sử dụng itertools.islice làm công việc:

from itertools import islice 
with open('filename') as f : 
    lines = islice(f,0,2*N-1) 
0

phương pháp mà nói đến cái tâm của tôi khi tôi đọc câu hỏi của bạn sử dụng một vòng lặp for nơi bạn cắt chuỗi thành nhiều (ví dụ như 100 bạn gọi) và lặp qua chuỗi con.

thestring = "" #your string 
steps = 100 #length of the strings you are going to use for iteration 
log = 0 
substring = thestring[:log+steps] #this is the string you will split and iterate through 
thelist = substring.split("//") 
for element in thelist: 
    if(element you want): 
     #do your thing with the line 
    else: 
     log = log+steps 
     # and go again from the start only with this offset 

bây giờ bạn có thể xem xét tất cả các phần tử đi qua toàn bộ chuỗi 2 triệu (!).

điều tốt nhất để làm ở đây là thực sự làm cho một hàm đệ quy từ này (nếu đó là những gì bạn muốn):

thestring = "" #your string 
steps = 100 #length of the strings you are going to use for iteration 

def iterateThroughHugeString(beginning): 
    substring = thestring[:beginning+steps] #this is the string you will split and iterate through 
    thelist = substring.split("//") 
    for element in thelist: 
     if(element you want): 
      #do your thing with the line 
     else: 
      iterateThroughHugeString(beginning+steps) 
      # and go again from the start only with this offset 
0

Vì bạn đang học Python nó sẽ là một thách thức đối với mô hình một giải pháp năng động đầy đủ. Đây là một khái niệm về cách bạn có thể mô hình hóa một.

Lưu ý: Đoạn mã sau chỉ hoạt động đối với (các) tệp đang ở định dạng đã cho (xem 'Dành cho trường hợp' trong câu hỏi). Do đó, nó là một giải pháp tĩnh.

num = (int(input("Enter delimiter: ")) * 2) 
with open("./data.txt") as myfile: 
    print ([next(myfile) for x in range(num-1)]) 

Bây giờ có ý tưởng, bạn có thể sử dụng đối sánh mẫu và v.v.

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