Làm thế nào để kiểm tra nếu chuỗi trống?


1420

Python có một cái gì đó giống như một biến chuỗi rỗng nơi bạn có thể làm không:

if myString == string.empty:

Bất kể, cách thanh lịch nhất để kiểm tra các giá trị chuỗi trống là gì? Tôi thấy mã hóa cứng ""mỗi lần để kiểm tra một chuỗi rỗng không tốt bằng.


2
Làm thế nào là ""không tốt?
NoName

Câu trả lời:


2117

Các chuỗi rỗng là "giả" , có nghĩa là chúng được coi là sai trong ngữ cảnh Boolean, vì vậy bạn chỉ có thể làm điều này:

if not myString:

Đây là cách ưa thích nếu bạn biết rằng biến của bạn là một chuỗi. Nếu biến của bạn cũng có thể là một số loại khác thì bạn nên sử dụng myString == "". Xem tài liệu về Kiểm tra giá trị thật cho các giá trị khác sai trong bối cảnh Boolean.


183
Hãy cẩn thận, vì rất nhiều thứ khác là sai.
Ignacio Vazquez-Abrams

9
Tôi chưa bao giờ nghe về thuật ngữ giả trước đây. Có nghĩa là nó trả về sai?
Joan Venge

41
@Joan: Nó đánh giá là sai trong bối cảnh boolean.
Ignacio Vazquez-Abrams

54
OP muốn biết nếu biến là một chuỗi rỗng, nhưng bạn cũng sẽ nhập vào if not myString:khối nếu myStringđược None, 0, Falsevv Vì vậy, nếu bạn không chắc chắn loại gì myStringlà, bạn nên sử dụng if myString == "":để xác định xem nó là một chuỗi rỗng như trái ngược với một số giá trị giả khác.
Andrew Clark

15
@AndrewClark, trong trường hợp như vậy, thay vì một chuỗi if myString == ...biểu thức, chúng ta có thể sử dụng if myString in (None, '')hoặc theo @Bartek,if myString in (None, '') or not myString.strip()
Stew

414

Từ PEP 8 , trong phần Khuyến nghị lập trình trên mạng :

Đối với các chuỗi, (chuỗi, danh sách, bộ dữ liệu), sử dụng thực tế là các chuỗi trống là sai.

Vì vậy, bạn nên sử dụng:

if not some_string:

hoặc là:

if some_string:

Chỉ cần làm rõ, các chuỗi được đánh giá đến Falsehoặc Truetrong bối cảnh Boolean nếu chúng trống hoặc không. Họ là không bằng nhau để Falsehoặc True.


24
Thật tuyệt khi bạn bao gồm các tham chiếu đến PEP!
Felix

3
Tái bút: Trong phần bảo vệ của PEP, người ta có thể lập luận rằng nói " x là sai " (viết thường là sai ) đã có nghĩa như vậy, hơn là ý nghĩa x == False. Nhưng IMHO việc làm rõ vẫn được hoan nghênh cho đối tượng mục tiêu.
MestreLion

234

Cách thanh lịch nhất có lẽ chỉ đơn giản là kiểm tra xem nó đúng hay sai, ví dụ:

if not my_string:

Tuy nhiên, bạn có thể muốn tước khoảng trắng vì:

 >>> bool("")
 False
 >>> bool("   ")
 True
 >>> bool("   ".strip())
 False

Tuy nhiên, có lẽ bạn nên rõ ràng hơn một chút trong trường hợp này, trừ khi bạn biết chắc rằng chuỗi này đã vượt qua một số loại xác nhận và là một chuỗi có thể được kiểm tra theo cách này.


88

Tôi sẽ kiểm tra sự không đồng đều trước khi tước. Ngoài ra, tôi sẽ sử dụng thực tế là các chuỗi rỗng là Sai (hoặc Falsy). Cách tiếp cận này tương tự như StringUtils.isBlank hoặc Guava's String.isNullOrEmpty của Apache

Đây là những gì tôi sẽ sử dụng để kiểm tra nếu một chuỗi là Không HOẶC Trống HOẶC Trống:

def isBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return False
    #myString is None OR myString is empty or blank
    return True

Và, hoàn toàn ngược lại để kiểm tra xem một chuỗi không phải là Không có sản phẩm nào.

def isNotBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return True
    #myString is None OR myString is empty or blank
    return False

Các hình thức ngắn gọn hơn của mã trên:

def isBlank (myString):
    return not (myString and myString.strip())

def isNotBlank (myString):
    return bool(myString and myString.strip())

tại sao không if mystring and not mystring.strip()?
Migol

1
Nó khác với string and not string.isspace()như thế nào?
Andrea Corbellini

7
Súc tích hơn cho những người quan tâm đến những điều như vậy: def isBlank(s): return not (s and s.strip())def isNotBlank(s): return s and s.strip().
Carl

49

Tôi đã từng viết một cái gì đó tương tự như câu trả lời của Bartek và lấy cảm hứng từ javascript:

def is_not_blank(s):
    return bool(s and s.strip())

Kiểm tra:

print is_not_blank("")    # False
print is_not_blank("   ") # False
print is_not_blank("ok")  # True
print is_not_blank(None)  # False

Tại sao không chỉreturn bool(s.strip())
anilbey

1
AttributeError: 'NoneType' object has no attribute 'strip'
hầm

28

Cách thực sự vững chắc duy nhất để làm điều này là như sau:

if "".__eq__(myString):

Tất cả các giải pháp khác có vấn đề có thể xảy ra và các trường hợp cạnh mà kiểm tra có thể thất bại.

len(myString)==0có thể thất bại nếu myStringlà một đối tượng của một lớp kế thừa từ strvà ghi đè __len__()phương thức.

Tương tự myString == ""myString.__eq__("")có thể thất bại nếu myStringghi đè __eq__()__ne__().

Vì một số lý do "" == myStringcũng bị lừa nếu myStringghi đè __eq__().

myString is """" is myStringlà tương đương. Cả hai sẽ thất bại nếu myStringthực sự không phải là một chuỗi mà là một lớp con của chuỗi (cả hai sẽ trả về False). Ngoài ra, vì chúng là kiểm tra danh tính, lý do duy nhất khiến chúng hoạt động là do Python sử dụng String Pooling (còn được gọi là String Internment) sử dụng cùng một thể hiện của chuỗi nếu nó được thực hiện (xem tại đây: Tại sao so sánh các chuỗi sử dụng '= = 'hoặc' là 'đôi khi tạo ra một kết quả khác nhau? ). Và ""được thực tập từ đầu trong CPython

Vấn đề lớn với kiểm tra danh tính là String Internment là (theo như tôi có thể tìm thấy) rằng nó không được chuẩn hóa mà chuỗi nào được thực hiện. Điều đó có nghĩa là, về mặt lý thuyết ""là không cần thiết thực tập và đó là phụ thuộc thực hiện.

Cách duy nhất để làm điều này thực sự không thể bị lừa là cách được đề cập ở phần đầu : "".__eq__(myString). Vì điều này gọi một cách rõ ràng __eq__()phương thức của chuỗi rỗng, nó không thể bị đánh lừa bằng cách ghi đè bất kỳ phương thức nào trong myString và hoạt động mạnh mẽ với các lớp con của str.

Cũng dựa vào độ sai lệch của chuỗi có thể không hoạt động nếu đối tượng ghi đè __bool__()phương thức của nó .

Đây không chỉ là công việc lý thuyết mà còn thực sự có liên quan trong việc sử dụng thực tế vì tôi đã thấy các khung và thư viện phân lớp strtrước đó và việc sử dụng myString is ""có thể trả về một đầu ra sai ở đó.

Ngoài ra, so sánh các chuỗi sử dụng isnói chung là một cái bẫy khá xấu vì đôi khi nó sẽ hoạt động chính xác, nhưng không phải lúc khác, vì việc gộp chuỗi tuân theo các quy tắc khá kỳ lạ.

Điều đó nói rằng, trong hầu hết các trường hợp, tất cả các giải pháp được đề cập sẽ hoạt động chính xác. Đây là bài viết chủ yếu là công việc học tập.


2
@simpleuser bạn dĩ nhiên là đúng. Trong thế giới thực, việc sử dụng sai lệch của chuỗi hoặc so sánh nó với một chuỗi trống là hoàn toàn ổn. Câu trả lời ở đây là quá mức về mục đích.
Dakkaron

thực sự, sử dụng eq_ ?
tàu cao tốc

làm việc tuyệt vời, cảm ơn bạn!
eugene.polschikov

14

Kiểm tra chuỗi trống hoặc trống (cách ngắn hơn):

if myString.strip():
    print("it's not an empty or blank string")
else:
    print("it's an empty or blank string")

7
Nếu myString = None, nó sẽ đưa ra một ngoại lệ. Sử dụng tốt hơn câu trả lời
Dominik

9

Nếu bạn muốn phân biệt giữa các chuỗi rỗng và null, tôi sẽ đề nghị sử dụng if len(string), nếu không, tôi khuyên bạn nên sử dụng đơn giản if stringnhư những người khác đã nói. Mặc dù vậy, sự cảnh báo về các chuỗi đầy khoảng trắng vẫn được áp dụng, vì vậy đừng quên strip.


Tôi không biết lý do tại sao bạn muốn tránh sử dụng "", trừ khi nó ảnh hưởng đến hiệu suất bằng cách nào đó, nhưng tôi thích câu trả lời của bạn cho câu trả lời có hàng trăm lần, vì nó ít gây nhầm lẫn. Tuy nhiên, tôi muốn chỉ ra rằng một danh sách trống cũng là Sai, rõ ràng.
Brōtsyorfuzthrāx

7

if stringname:đưa ra một falsekhi chuỗi rỗng. Tôi đoán nó không thể đơn giản hơn thế này.


6
a = ''
b = '   '
a.isspace() -> False
b.isspace() -> True

1
Thực sự không hiểu những gì giải pháp này đạt được. Câu hỏi là về việc kiểm tra xem một chuỗi có trống không. Nếu bạn đặt a='a'bạn sẽ nhận được a.isspace() -> False, nhưng atài khoản đó sẽ không phải là một chuỗi trống.
Adrian Keister

6

Tôi thấy mã hóa cứng (sic) "" mỗi lần kiểm tra một chuỗi trống không tốt bằng.

Cách tiếp cận mã sạch

Làm điều này: foo == ""là thực hành rất xấu. ""là một giá trị kỳ diệu. Bạn không bao giờ nên kiểm tra các giá trị ma thuật (thường được gọi là số ma thuật )

Những gì bạn nên làm là so sánh với một tên biến mô tả.

Tên biến mô tả

Người ta có thể nghĩ rằng "blank_ chuỗi" là một tên biến mô tả. Nó không phải là .

Trước khi bạn đi và làm empty_string = "" và nghĩ rằng bạn có một tên biến tuyệt vời để so sánh với. Đây không phải là "tên biến mô tả" nghĩa là gì.

Một tên biến mô tả tốt được dựa trên bối cảnh của nó. Bạn phải suy nghĩ về chuỗi rỗng là gì .

  • Nó đến từ đâu.
  • Tại sao nó ở đó.
  • Tại sao bạn cần kiểm tra nó.

Ví dụ trường mẫu đơn giản

Bạn đang xây dựng một biểu mẫu nơi người dùng có thể nhập các giá trị. Bạn muốn kiểm tra xem người dùng có viết gì hay không.

Một tên biến tốt có thể là not_filled_in

Điều này làm cho mã rất dễ đọc

if formfields.name == not_filled_in:
    raise ValueError("We need your name")

Ví dụ phân tích cú pháp CSV kỹ lưỡng

Bạn đang phân tích tệp CSV và muốn chuỗi trống được phân tích cú pháp như None

(Vì CSV hoàn toàn dựa trên văn bản, nó không thể đại diện None mà không sử dụng các từ khóa được xác định trước)

Một tên biến tốt có thể là CSV_NONE

Điều này giúp mã dễ dàng thay đổi và thích ứng nếu bạn có tệp CSV mới đại diện cho Nonemột chuỗi khác""

if csvfield == CSV_NONE:
    csvfield = None

Không có câu hỏi về việc nếu đoạn mã này là chính xác. Nó là khá rõ ràng rằng nó làm những gì nó nên làm.

So sánh điều này với

if csvfield == EMPTY_STRING:
    csvfield = None

Câu hỏi đầu tiên ở đây là, tại sao chuỗi trống xứng đáng được đối xử đặc biệt?

Điều này sẽ nói với các lập trình viên tương lai rằng một chuỗi rỗng phải luôn luôn được coi là None.

Điều này là do nó trộn logic kinh doanh (Giá trị CSV phải là gì None) với việc triển khai mã (Chúng ta thực sự so sánh với cái gì)

Cần phải có một sự tách biệt mối quan tâm giữa hai.


1
Có ai thực sự cần phải đi đến nhiều rắc rối để tránh "" không? Trong bối cảnh so sánh, một chuỗi trống có thể có ý nghĩa gì khác?

Khi tôi viết trong câu trả lời của mình, CSV không thể biểu thị null mà không sử dụng chuỗi. Nếu bạn là bối cảnh miễn phí thì xin chúc mừng! Hầu hết các mã không.
Firelynx

2
bạn nói "not_fills_in" có tính mô tả hơn "blank_ chuỗi"? Tôi nói bạn cao.
Tuncay Göncüoğlu

@ TuncayGöncüoğlu "Chuỗi rỗng" không mô tả câu lệnh if kiểm tra để làm gì.
Firelynx

5
Tôi sẽ không đồng ý với câu trả lời đó. Số ma thuật là xấu, điều đó có ý nghĩa. Giá trị ma thuật nói chung là tốt. Nhưng ""không phải là một giá trị ma thuật, giống như True, Falsehoặc Nonekhông phải là giá trị ma thuật.
Dakkaron

5

Còn cái này thì sao? Có lẽ nó không phải là "thanh lịch nhất", nhưng nó có vẻ khá đầy đủ và rõ ràng:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...

Đối với hầu hết các mục đích, một chuỗi chứa khoảng trống không "trống".
Chris Johnson

Tôi giả sử bạn có ý nghĩa gì ngoài khoảng trắng? Bạn đang đề cập đến việc tôi sử dụng dải ()? Đối với hầu hết các mục đích mà là trống rỗng! Nó là vô lý phổ biến để ghép một cái gì đó như s.trim ().
IsEmpty

Xin chào @Chris Johnson, bạn có thấy rằng NHIỀU câu trả lời ở đây cũng sử dụng dải () không? Bạn đã bỏ phiếu tất cả chúng ta, hoặc chỉ tôi?
BuvinJ

4

Trả lời @ 1290. Xin lỗi, không có cách nào để định dạng khối trong ý kiến. Các Nonegiá trị không phải là một chuỗi rỗng bằng Python, và không phải là (dấu cách). Câu trả lời từ Andrew Clark là câu trả lời đúng : if not myString. Câu trả lời từ @rouble là dành riêng cho ứng dụng và không trả lời câu hỏi của OP. Bạn sẽ gặp rắc rối nếu bạn áp dụng một định nghĩa đặc biệt về chuỗi "trống" là gì. Cụ thể, hành vi tiêu chuẩn là str(None)tạo ra 'None', một chuỗi không trống.

Tuy nhiên, nếu bạn phải coi Nonevà (khoảng trắng) là chuỗi "trống", đây là cách tốt hơn:

class weirdstr(str):
    def __new__(cls, content):
        return str.__new__(cls, content if content is not None else '')
    def __nonzero__(self):
        return bool(self.strip())

Ví dụ:

>>> normal = weirdstr('word')
>>> print normal, bool(normal)
word True

>>> spaces = weirdstr('   ')
>>> print spaces, bool(spaces)
    False

>>> blank = weirdstr('')
>>> print blank, bool(blank)
 False

>>> none = weirdstr(None)
>>> print none, bool(none)
 False

>>> if not spaces:
...     print 'This is a so-called blank string'
... 
This is a so-called blank string

Đáp ứng các yêu cầu @rouble trong khi không phá vỡ boolhành vi dự kiến của chuỗi.


python -c "if (str(None) == 'None'): print ('OMG, WHY ??')"
Yordan Georgiev

3

Tôi thấy điều này thanh lịch vì nó đảm bảo rằng đó là một chuỗi và kiểm tra độ dài của nó:

def empty(mystring):
    assert isinstance(mystring, str)
    if len(mystring) == 0:
        return True
    else:
        return False

Cảnh báo, xác nhận có nghĩa là một công cụ gỡ lỗi và được tối ưu hóa nếu bạn vượt qua -Ocờ hoặc đặt PYTHONOPTIMIZEbiến env.
SilentVoid

2

Một cách dễ dàng khác có thể là xác định một hàm đơn giản:

def isStringEmpty(inputString):
    if len(inputString) == 0:
        return True
    else:
        return False

3
câu trả lời từ thảo quả sẽ đầy đủ hơn nếu chúng ta muốn kiểm tra xem đầu vào có phải là chuỗi hay không
tanzil

1
not str(myString)

Biểu thức này là True cho các chuỗi trống. Tất cả các chuỗi không trống, các đối tượng Không và không chuỗi đều tạo ra Sai, với cảnh báo rằng các đối tượng có thể ghi đè __str__ để cản trở logic này bằng cách trả về giá trị giả.




0

Khi bạn đang đọc tệp theo dòng và muốn xác định, dòng nào trống, hãy đảm bảo bạn sẽ sử dụng .strip(), bởi vì có dòng ký tự mới trong dòng "trống":

lines = open("my_file.log", "r").readlines()

for line in lines:
    if not line.strip():
        continue

    # your code for non-empty lines

0
str = ""
if not str:
   print "Empty String"
if(len(str)==0):
   print "Empty String"

0

Nếu bạn chỉ sử dụng

not var1 

không thể phân biệt một biến là boolean Falsetừ một chuỗi rỗng '':

var1 = ''
not var1
> True

var1 = False
not var1
> True

Tuy nhiên, nếu bạn thêm một điều kiện đơn giản vào tập lệnh của mình, sự khác biệt được tạo ra:

var1  = False
not var1 and var1 != ''
> True

var1 = ''
not var1 and var1 != ''
> False

0

Trong trường hợp điều này hữu ích với ai đó, đây là một chức năng nhanh chóng được tôi xây dựng để thay thế các chuỗi trống bằng N / A trong danh sách danh sách (python 2).

y = [["1","2",""],["1","4",""]]

def replace_blank_strings_in_lists_of_lists(list_of_lists):
    new_list = []
    for one_list in list_of_lists:
        new_one_list = []
        for element in one_list:
            if element:
                new_one_list.append(element)
            else:
                new_one_list.append("N/A")
        new_list.append(new_one_list)
    return new_list


x= replace_blank_strings_in_lists_of_lists(y)
print x

Điều này hữu ích để đăng danh sách danh sách lên cơ sở dữ liệu mysql không chấp nhận khoảng trống cho các trường nhất định (các trường được đánh dấu là NN trong lược đồ. Trong trường hợp của tôi, đây là do khóa chính tổng hợp).


-1

Tôi đã thực hiện một số thử nghiệm với các chuỗi như '', '', '\ n', v.v. Tôi muốn isNotWhitespace là True khi và chỉ khi biến foo là một chuỗi có ít nhất một ký tự không phải khoảng trắng. Tôi đang sử dụng Python 3.6. Đây là những gì tôi đã kết thúc với:

isWhitespace = str is type(foo) and not foo.strip()
isNotWhitespace = str is type(foo) and not not foo.strip()

Gói này trong một định nghĩa phương pháp nếu muốn.


-3

Như prmatta đăng ở trên, nhưng với sai lầm.

def isNoneOrEmptyOrBlankString (myString):
    if myString:
        if not myString.strip():
            return True
        else:
            return False
    return False

Chỉ cần kiểm tra: trả về mã của ông True cho """ "và False cho "a"(giống như mong đợi). Mã của bạn trả về giống nhau, ngoại trừ chuỗi trống, nó trả về True, những gì không nên.
AbcAeffchen

Sry quá mệt mỏi: Mã của bạn trả về Sai cho chuỗi trống.
AbcAeffchen

Mã này là sai. Bạn trả về Sai nếu một chuỗi trống hoặc không có.
rúp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.