2011-08-01 32 views
9

Tôi có một danh sách giống như thế này:Python danh sách có điều kiện tham gia

[ 
    'A', 
    'must', 
    'see', 
    'is', 
    'the', 
    'Willaurie', 
    ',', 
    'which', 
    'sank', 
    'after', 
    'genoegfuuu', 
    'damaged', 
    'in', 
    'a', 
    'storm', 
    'in', 
    '1989', 
    '.' 
] 

Như bạn thấy, có dấu chấm câu. Tôi muốn gọi .join bằng cách sử dụng một khoảng trống, ngoại trừ các trường hợp mà chuỗi là dấu câu, sau đó tôi không muốn một dấu phân cách.

Cách tốt nhất để làm điều này là gì?
Tôi đã thử một lúc và các giải pháp của tôi đang trở nên quá phức tạp đối với những gì có vẻ như là một công việc đơn giản.

Cảm ơn

Trả lời

12

Module string có một danh sách chứa tất cả các ký tự dấu.

import string 
string = ''.join([('' if c in string.punctuation else ' ')+c for c in wordlist]).strip() 
+0

Tốt hơn là không nên đặt tên biến "chuỗi" sau khi bạn vừa nhập mô-đun có cùng tên. Sau mã này, "chuỗi" có thể là biến kiểu str, không phải là mô-đun và điều này có thể gây nhầm lẫn cho những người thiếu kinh nghiệm. – MihanEntalpo

1

Giống như rất

re.sub(r'\s+(?=\W)', '', ' '.join(['A', 'must', 'see', 'is', 'the', 'Willaurie', ',', 'which', 'sank', 'after', 'genoegfuuu', 'damaged', 'in', 'a', 'storm', 'in', '1989', '.'])) 
+0

này khiến tôi học được điều gì mới về regex. Những thứ tuyệt vời. – gEr

2
>>> ''.join([('' if i in set(",.!?") else ' ') + i for i in words]).strip() 
'A must see is the Willaurie, which sank after genoegfuuu damaged in a storm in 1989.' 
1

Làm cách nào để sử dụng bộ lọc?

words = ['A', 'must', 'see', 'is', 'the', 'Willaurie', ',', 'which', 'sank', 'after', 'genoegfuuu', 'damaged', 'in', 'a', 'storm', 'in', '1989', '.'] 
' '.join(filter(lambda x: x not in string.punctuation, words)) 
+0

Điều này không trả lời câu hỏi - nó hoàn toàn loại bỏ dấu chấm câu. – Logan

4

Bạn đã có câu trả lời, nhưng chỉ muốn thêm vào, không phải tất cả các dấu chấm câu đều bị mắc kẹt ở phía bên tay trái. Nếu bạn muốn giải quyết các câu tổng quát hơn, bạn có thể có ví dụ như dấu ngoặc đơn hoặc dấu nháy đơn và bạn không muốn kết thúc bằng một cái gì đó như:

Đó là một bộ phim tuyệt vời (tốt nhất tôi đã xem)

Tôi muốn nói thật vô nghĩa khi tạo ra một số lớp lót khó chịu, chỉ để thực hiện điều này theo cách đa chiều nhất. Nếu bạn không cần giải pháp siêu nhanh, bạn có thể xem xét giải quyết nó bước-by-step, ví dụ:

import re 
s = ['It', "'", 's', 'a', 'great', 'movie', 
    '(', 'best', 'I', "'", 've', 'seen', ')'] 

s = " ".join(s) # join normally 
s = re.sub(" ([,.;\)])", lambda m: m.group(1), s) # stick to left 
s = re.sub("([\(]) ", lambda m: m.group(1), s) # stick to right 
s = re.sub(" ([']) ", lambda m: m.group(1), s) # join both sides 

print s # It's a great movie (best I've seen) 

Nó khá linh hoạt và bạn có thể xác định những dấu chấm câu được xử lý bởi từng quy tắc ... Nó có 4 dòng mặc dù, vì vậy bạn có thể không thích nó. Bất kể bạn chọn phương pháp nào, có thể sẽ có một số câu không hoạt động chính xác và cần trường hợp đặc biệt, vì vậy một lớp lót có thể chỉ là một lựa chọn tồi.

EDIT: Trên thực tế, bạn có thể ký hợp đồng giải pháp trên để một dòng, nhưng như đã nói trước đây, tôi khá chắc chắn rằng có nhiều trường hợp để xem xét:

print re.sub("([,.;\)]|[\(] | ['])", lambda m: m.group(1).strip(), " ".join(s)) 
+0

Thật vậy, có nhiều trường hợp cạnh. Tôi đã vào tình huống này bằng cách sử dụng NLTK để tokenize văn bản của tôi và không chú ý đến từ tokenizer. Khá lộn xộn bây giờ. Cảm ơn vi đa trả lơi. – gEr

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