2012-03-09 25 views
16

Trong khi tôi biết rằng có khả năng:Python Di char cuối cùng từ chuỗi và gửi lại

>>> a = "abc" 
>>> result = a[-1] 
>>> a = a[:-1] 

Bây giờ tôi cũng biết rằng dây là không thay đổi và do đó một cái gì đó như thế này:

>>> a.pop() 
c 

là không thể.

Nhưng đây thực sự là cách ưa thích?

+0

Tôi đã cố gắng thêm , không biết tại sao nó không hoạt động. –

+2

Nó thực sự phụ thuộc vào những gì bạn đang cố gắng làm và tầm quan trọng của việc tối ưu hóa mã. Tôi nghĩ rằng trong hầu hết các trường hợp, chỉ cần trả về một chuỗi mới được ưa thích hơn là tạo một loại khác hoặc sử dụng một danh sách. – dave

+0

Nếu bạn phải làm điều này thường xuyên, hãy suy nghĩ lại thuật toán của bạn. – delnan

Trả lời

27

Chuỗi là "không thay đổi" vì lý do chính đáng: Nó thực sự tiết kiệm rất nhiều cơn đau đầu, thường xuyên hơn bạn nghĩ. Nó cũng cho phép python rất thông minh về việc tối ưu hóa việc sử dụng chúng. Nếu bạn muốn xử lý chuỗi của bạn trong từng bước, bạn có thể kéo ra một phần của nó với split() hoặc tách nó thành hai phần bằng chỉ số:

a = "abc" 
a, result = a[:-1], a[-1] 

Điều này cho thấy rằng bạn đang tách chuỗi của bạn trong hai.Nếu bạn sẽ được kiểm tra mỗi byte của chuỗi, bạn có thể lặp trên nó (ngược lại, nếu bạn muốn):

for result in reversed(a): 
    ... 

tôi nên thêm này có vẻ một chút giả tạo: string của bạn có nhiều khả năng có một số dấu tách, và sau đó bạn sẽ sử dụng split:

ans = "foo,blah,etc." 
for a in ans.split(","): 
    ... 
5

Đây không chỉ là cách ưa thích, đó là cách hợp lý duy nhất. Bởi vì chuỗi là bất biến, để "loại bỏ" một char từ một chuỗi, bạn phải tạo một chuỗi mới bất cứ khi nào bạn muốn có một giá trị chuỗi khác nhau.

Bạn có thể tự hỏi tại sao chuỗi không thay đổi được, vì bạn phải tạo một chuỗi hoàn toàn mới mỗi khi bạn thay đổi ký tự. Sau khi tất cả, chuỗi C chỉ là mảng ký tự và do đó có thể thay đổi và một số ngôn ngữ hỗ trợ chuỗi rõ ràng hơn C cho phép các chuỗi có thể thay đổi được. Có hai lý do để có chuỗi bất biến: an ninh/an toàn và hiệu suất.

Bảo mật có lẽ là lý do quan trọng nhất đối với các chuỗi không thay đổi được. Khi các chuỗi không thay đổi, bạn không thể chuyển một chuỗi vào một số thư viện và sau đó có chuỗi thay đổi từ dưới chân của bạn khi bạn không mong đợi nó. Bạn có thể thắc mắc thư viện nào sẽ thay đổi tham số chuỗi, nhưng nếu bạn đang chuyển mã cho khách hàng, bạn không thể kiểm soát phiên bản thư viện chuẩn và khách hàng độc hại có thể thay đổi thư viện chuẩn của họ để phá vỡ chương trình của bạn và tìm hiểu thêm về nội bộ của nó. Các đối tượng không thay đổi cũng dễ dàng hơn để giải thích, điều này thực sự quan trọng khi bạn cố gắng chứng minh rằng hệ thống của bạn là an toàn chống lại các mối đe dọa cụ thể. Điều này dễ dàng lý luận là đặc biệt quan trọng đối với an toàn thread, kể từ khi các đối tượng bất biến được tự động thread-an toàn.

Hiệu suất đáng ngạc nhiên thường tốt hơn đối với các chuỗi không thay đổi được. Bất cứ khi nào bạn lấy một đoạn của một chuỗi, thời gian chạy Python chỉ đặt một khung nhìn trên chuỗi gốc, do đó không có phân bổ chuỗi mới nào. Vì chuỗi là bất biến, bạn có được ngữ nghĩa sao chép mà không thực sự sao chép, đó là một chiến thắng hiệu suất thực sự.

Eric Lippert giải thích thêm về lý do đằng sau các chuỗi không thay đổi (trong C#, không phải Python) here.

1

Có, chuỗi python không thay đổi được và mọi sửa đổi sẽ dẫn đến việc tạo chuỗi mới. Đây là cách nó được thực hiện chủ yếu.

Vì vậy, hãy tiếp tục với nó.

3

Từ ngữ chính xác của câu hỏi khiến tôi nghĩ điều đó là không thể.

return với tôi có nghĩa là bạn có một hàm, bạn đã chuyển một chuỗi làm tham số.

Bạn không thể thay đổi thông số này. Việc gán cho nó sẽ chỉ thay đổi giá trị của tham số bên trong hàm, không phải là chuỗi được truyền vào. Ví dụ.

>>> def removeAndReturnLastCharacter(a): 
     c = a[-1] 
     a = a[:-1] 
     return c 

>>> b = "Hello, Gaukler!" 
>>> removeAndReturnLastCharacter(b) 
! 

>>> b # b has not been changed 
Hello, Gaukler! 
Các vấn đề liên quan