01/10/2018, 14:37
%s trong Python có tác dụng gì?
Em source 2 code này ra vẫn giống nhau
cars = 100
print (“There are %s cars available.” % cars)
cars = 100
print (“There are”, cars, “cars available.”)
Anh chị nào biết tác dụng của %s giải thích em với ạ.
Bài liên quan
Nhiều ngôn ngữ bắt chước cách định dạng của ngôn ngữ C. Bạn tra cứu với từ khóa printf format string để xem giải thích rõ hơn. Nói chung là để định dạng việc in ra cho đẹp, dễ hơn trong việc gom các biến/biểu thức lại một chỗ, dễ gỡ rối khi cần.
Đừng nói thế dễ gây war. Đơn giản chỉ là vì C đi trước và các ngôn ngữ khác follow theo để các lập trình viên không bị rắc rối quá nhiều vì phải học lại nhiều syntax và standard.
Việc sử dụng
%s
dùng để inject data vào String có hai tác dụng.A post was merged into an existing topic: Topic chứa các reply được cho là off-topic - version 2
Mình có thể hiểu đc vấn đề rồi , cảm ơn bạn ^^
Có nhiều cách format lắm.
”number $a == number $b”
trong PHP”hello “ + “world”
Trong đó, format string là cách low-level, nhưng lại là cách mà developer có nhiều tuỳ chỉnh nhất.
C nó làm luôn kiểu format string và chỉ có support mỗi tính năng đó cho string nên dễ gây ức chế với người mới tiếp cận.
Là mỗi format string có tác dụng khác nhau phải không ạ
Giống kiểu %s là giúp code ngắn gọn hơn ( Mình mới nhập môn Python nên chỉ biết mỗi %s )
tác dụng như nhau hết: để định dạng chuỗi, chỉ khác chỗ dễ đọc, hoặc dễ học, hoặc dễ code, hoặc chạy nhanh thôi.
Python có nhiều kiểu lắm: %, {}, hoặc template string: https://docs.python.org/3.6/library/string.html, https://pyformat.info/
%s giúp code ngắn hơn nhưng có khi đọc vào chả hiểu gì, ví dụ
{} thì dễ học, dễ code hơn, vì ko cần nhớ mấy kí tự sau dấu %, ví dụ
hoặc tránh truyền đi truyền lại 1 biến nào đó:
v.v… nói chung là nên xài {} thay cho %xyz
string + string thì chậm, string builder thì lẹ hơn
v.v…
Tổ chức code và viết sao với đoạn code dài vẫn đọc được. Cái đó quan trọng hơn là làm cho code ngắn hơn.
Tại sao “string + string” lại chậm hơn “stringbuilder” vậy ?
tại vì nó tốn thời gian tạo ra chuỗi mới mỗi lần + vào, còn stringbuilder thì nó ko tạo chuỗi mới mà xài thẳng chuỗi cũ luôn, và nó cấp phát bộ nhớ cho mảng ký tự mới cho chuỗi cũ 1 cách “thông minh” hơn so với a + b
python ko có stringbuilder nên string + string với .format cũng gần như nhau rồi, python 3.6 có cái string interpolation nghe nói lẹ hơn tí. Mấy ngôn ngữ khác như C# Java C++ mới thấy string + string nó chậm hơn stringbuilder.
mấy cái tốc độ nhanh chậm thì để sau cùng hẵn tính, viết ra đủ yêu cầu cái đã rồi mới lo optimize tốc độ sau cùng. Nếu viết string + string dễ đoc dễ hiểu thì cứ viết theo dễ đọc dễ hiểu, khi nào chậm quá thì mới tính viết cách khác… Bởi vậy mình viết nó có 1 dòng be bé thôi mà lại gây khó hiểu :V
Cảm ơn bạn đã giải thích vấn đề .
string + string
không chậm hơnstringbuilder
nhé. Cái này là case by case cần nhận thức đúng. Vấn đề gặp phải của việc cộng hai String là trong Java String sử dụng String pool (Khái niệm tự Google nhé cho lớn) dẫn đến String là immutabe type. Nghĩa là String là không thể thay đổi được. Cụ thể như sau:Ta có một tổ chức bộ nhớ kiểu.
Khi ta lưu một String vào String Pool này ví dụ từ
Hello
thì biểu thức thực hiện như sau.Khi thực hiện cộng tiếp một chuỗi vào chuỗi kế tiếp thì điều gì sẽ xảy ra. Có hai trường hợp, 1 là vị trí
index == 5
chưa bị chiếm dụng vậy việc đơn giản là cộng tiếpworld
vào trong pool là xong. SAI. Hoàn toàn không có trường hợp này. String pool được sinh ra để đảm bảo là String sẽ được tối ưu hoá cho việc sử dụng lại nhiều lần. Vậy nên vị trí index 0 chỉ có thể trả về String làHello
vậy điều gì sẽ xảy ra. Các bước thuật toán bao gồm.Hello
ra.Hello
.Hello
vàworld
Hello world
vào String poolTổng cộng là ta mất 5 bước thuật toán trong tưởng tượng. (Vì thực tế nó không chính xác như thế) Với StringBuilder thì điều gì sẽ xảy ra. Phương án là thay vì lưu trực tiếp chuỗi vào trong StringPool, ta cache lại chuỗi này trong một char array. Vậy khi cộng hai String, ta sẽ làm các bước sau.
Hello
ra.Hello
.Hello
vàworld
Hello world
vào ArrayKhông khác gì việc cộng String trong tưởng tượng. Lí do là vì Array cũng không thể thay đổi được kích thước sau khi đã khai báo. Tuy nhiên điểm khác biệt giữa Array và String đấy là Array thì không phải là một immutabe type. (Bằng chứng là người ta vẫn đi tìm immutable array đó thôi) StringBuilder triển khai một kĩ thuật trong xử lý Array. Tức là thay vì tạo một array có kích thước bằng với kích thước của
Hello
, StringBuilder tạo ra một đoạn buffer lớn hơn kích thước đó (Cụ thể giá trị mặc định bằng 16) để khi tiếp tục thực hiện việc cộng, sẽ có hai trường hợp xảy ra.Hello
ra.Hello
.Hello
vàworld
3.1 Vì Array có độ dài bằng 16 nên copy String mới vào đây luôn. Tốn số bước lưu bằng kích thước
world
bằng 6.3.2 Nếu kích thước vượt quá kích thước hiện tại. Tìm một vùng nhớ có độ dài bằng 11 gần nhất. Số bước thuật toán tốn bằng việc thanh ghi nhảy bao nhiêu lần.
Hello world
vào Array. Tốn tiếp 11 bước thuật toán nữa.Rõ ràng là chỉ tính từ bước số 4 thì 11++ luôn lớn hơn rất nhiều 6. Và nếu String cũ mà dài thì còn lớn hơn rất rất là nhiều nữa. Vậy xét một cách nào đó thì
string + string
chậm hơnstringbuilder
nhưng có một số side effect sau.StringBuilder(int)
dùng để khởi tạo giá trị độ lớn ban đầu cho Char Array.javap -c
ra xem thử. Vì máy mình không có cài Java tại lâu rồi nhảy qua code ML xin được lấy tạm code ở trên SO.Lưu ý là điều này chỉ xảy ra khi bạn cộng String trong cùng một biểu thức (với java 6) hoặc trong cùng một code block (với java 8) (cần dẫn nguồn vì mình không nhớ).
Đọc source code của StringBuilder tại đây. StringBuffer thì tự tìm hiểu nhé dài quá.
Kết luận lại là không phải cứ thấy người ta bảo nó nhanh là nó sẽ nhanh. Trong lập trình thì không có bất kì một solution nào là tốt cho tất cả các trường hợp. Luôn phải trả một cái giá nào đó. Tuy nhiên đó là điều khiến chúng ta tăng lương. LoL…