2014-04-06 16 views
5

Xin lỗi vì tiêu đề mơ hồ, nhưng thật khó để giải thích ngắn gọn.Cách tốt nhất để tách từng phần tử chuỗi thứ n và hợp nhất thành mảng?

Về cơ bản, hãy tưởng tượng tôi có một danh sách (bằng Python) trông như thế này:

['a', 'b', 'c\nd', 'e', 'f\ng', 'h', 'i'] 

Từ đó, tôi muốn có được điều này:

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] 

Một cách tôi đã nghĩ đến việc làm điều này đã được sử dụng reduce như vậy:

reduce(lambda x, y: x + y.split('\n'), lst, []) 

Nhưng tôi không nghĩ điều này rất hiệu quả, vì nó không tận dụng lợi thế của thực tế là chúng ta biết mọi phần tử thứ n có dấu phân tách trong nó. Bất kỳ đề xuất?

Chỉnh sửa: để biết thêm thông tin về cách mảng được xây dựng, điều này có thể gây ra sự cố.

Tôi có văn bản dưới hình thức:

Ignorable line 
Field name 1|Field name 2|Field name 3|Field name 4 
Value 1|Value 2|Value 3|Value 4 
Value 1|Value 2|Value 3|Value 4 
... 

đâu chúng ta có thể có một số lượng tùy ý các tên trường, và sẽ luôn luôn là một số lượng tương đương giá trị như tên trường trên đường dây. Lưu ý rằng chúng ta có thể có các dòng mới trong các giá trị. Chúng tôi chỉ biết rằng sẽ được phân tách bằng dấu '|'. Vì vậy, chúng ta có thể có

Value 1|This is an long 
value that extends over multiple 
lines|Value 3|Value 4 

Làm thế nào tôi hiện đang làm điều này là bằng cách làm một s.split('\n', 2) để chúng tôi có được tên trường trong chuỗi riêng của họ, và các giá trị trong chuỗi riêng của họ. Sau đó, khi tách các giá trị bằng '|', chúng ta sẽ nhận được danh sách biểu mẫu mà tôi đã đề cập ban đầu.

+1

những gì bạn có nghĩa là mọi phần tử thứ n ... nó trông giống như n của bạn thay đổi từ 3 đến 2 ... bên cạnh nó có thể rất nhiều nhanh ... trừ khi nó thực sự không, nhưng trong trường hợp đó bạn sẽ biết rằng đó là nút cổ chai của bạn ....tối ưu hóa sớm là gốc của tất cả các ác –

+1

Trong ví dụ, \ n luôn luôn theo mục thứ 3 (c là chữ thứ 3 của bảng chữ cái; f là số thứ 6). Tôi tò mò điều gì khiến bạn lấy danh sách ban đầu ở định dạng này. Có lẽ mã sẽ sạch hơn nếu bạn thay đổi cách bạn xây dựng danh sách gốc ... điều này giống như một công việc xung quanh cho một trình phân tích cú pháp bị hỏng. – ramcdougal

+0

@ramcdougal nó có thể là nó không phải là cách tốt nhất để xây dựng danh sách đó. Tôi sẽ cập nhật các bài viết với cách tôi đã nhận nó trong hình thức đó. – mp94

Trả lời

10

Bạn chỉ có thể thực hiện ('\n'.join(lst)).split() để nhận danh sách thứ 2.

In [17]: 

%timeit reduce(lambda x, y: x + y.split('\n'), lst, []) 
100000 loops, best of 3: 9.64 µs per loop 
In [18]: 

%timeit ('\n'.join(lst)).split() 
1000000 loops, best of 3: 1.09 µs per loop 

Nhờ @Joran Beasley đề xuất split() qua split('\n')!

Sửa

Bây giờ tôi thấy câu hỏi cập nhật của bạn, tôi nghĩ rằng chúng ta có thể tránh đi vào một tình huống như vậy trong đầu, nhìn thấy (sử dụng re):

In [71]: 

L=re.findall('([^|]+)\|', 
      ''.join(['|'+item+'|' if item.count('|')==3 else item for item in S.split('\n')[1:]])+'|') 
In [72]: 

zip(*[L[i::4] for i in range(4)]) #4 being the number of fields. 
Out[72]: 
[('Field name 1', 'Field name 2', 'Field name 3', 'Field name 4'), 
('Value 1', 'Value 2', 'Value 3', 'Value 4'), 
('Value 1', 
    'This is an longvalue that extends over multiplelines', 
    'Value 3', 
    'Value 4')] 

Trông giống như một bộ dữ liệu cho SAS ban đầu Tôi có đúng không?

+0

Điều đó chắc chắn nhanh hơn nhiều, nhưng cũng có thể có các dòng mới trong các phần tử khác (có thể là nhiều, số chưa biết). Tôi sẽ cập nhật bài đăng với thông tin đó. – mp94

+0

Nhận cơ hội giải quyết vấn đề? Nếu không, hãy xem chỉnh sửa. –

+0

Tôi đã làm, nhưng điều này sẽ làm việc là tốt. Đầu ra tôi phân tích cú pháp thực sự là yêu cầu của một truy vấn WQL, sử dụng tiện ích wmic trên Linux. Xem http://www.aldeid.com/wiki/Wmic-linux – mp94

2

sớm tối ưu hóa là gốc rễ của mọi tội lỗi

nếu bạn đang thực sự gặp vấn đề về hiệu suất vì mã này thats một chuyện, nhưng tôi nghi ngờ bạn đang có.

khi bạn tối ưu hóa bạn thường phải hy sinh khả năng đọc những gì tôi sẽ làm gì nếu nó là tôi

list(itertools.chain(*[item.split() for item in lst])) 

mà là rất rõ ràng những gì bạn làm

+1

Xin chào Joran, bạn có chắc điều này sẽ hoạt động không? Tôi nghĩ rằng nó nên là 'danh sách (itertools.chain (* [item.split() cho mục trong lst]))' –

+0

ahh của bạn hoàn toàn đúng câu trả lời của bạn là tốt hơn về độ rõ ràng tôi nghĩ anyway ("mặc dù id có lẽ chỉ cần sử dụng một phân chia bình thường không có dấu phân cách nhưng meh) –

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