Python: cách thành ngữ nhất để chuyển đổi Không thành chuỗi rỗng?


156

Cách thành ngữ nhất để làm như sau là gì?

def xstr(s):
    if s is None:
        return ''
    else:
        return s

s = xstr(a) + xstr(b)

cập nhật: Tôi đang kết hợp đề xuất của Tryptich để sử dụng str (s), điều này làm cho thói quen này hoạt động cho các loại khác ngoài các chuỗi. Tôi vô cùng ấn tượng với đề xuất lambda của Vinay Sajip, nhưng tôi muốn giữ mã của mình tương đối đơn giản.

def xstr(s):
    if s is None:
        return ''
    else:
        return str(s)

7
Tôi thích cú pháp ban đầu của bạn. Tôi nghĩ nó đã khá rõ ràng và dễ đọc.
GuiSim

1
@GuiSim: Tôi có thể bị thiên vị, nhưng câu trả lời của tôi đọc gần giống như một câu tiếng Anh thông thường ...
SilentGhost

1
"Nếu s là Không, thì trả về một chuỗi rỗng; nếu không, hãy trả về [chuỗi của] s." Mã từ câu hỏi cũng đọc giống như một câu tiếng Anh thông thường.

a) Nếu chuỗi sđến từ tra cứu chính tả nơi không tìm thấy khóa, thì hãy sử dụngdict.get(key, '')
smci

b) Nếu bạn chỉ muốn chuyển đổi chuỗi này cho định dạng đầu ra (ví dụ để in), thì bạn có thể trực tiếp thực hiện định dạng '... {}'. (dict.get (1)) `
smci

Câu trả lời:


94

Nếu bạn thực sự muốn chức năng của mình hoạt động như tích str()hợp, nhưng trả về một chuỗi trống khi đối số là Không có, hãy làm điều này:

def xstr(s):
    if s is None:
        return ''
    return str(s)

Tôi đang giữ cái khác, nhưng cảm ơn vì mẹo (s) để có thể xử lý nhiều loại. đẹp!
Đánh dấu Harrison

11
Hoặc đơn giản hơnxstr = lambda s: '' if s is None else str(s)
Michael Mior

2
Tôi thích đánh máy if not s:thay vìif s is None
guneysus 6/12/2015

6
@guneysus Họ không giống nhau: not False == Truenhưng False is None == False.
Lynn

Cảm ơn @Lynn bạn đã đúng. Tôi nhận ra lỗi của mình. Nhưng tôi biết (hoặc giả sử) sluôn là một loại str / unicode hoặc None. Vâng, Falselà một giá trị nhưng tôi thích cách này giúp tiết kiệm bàn phím và mắt của tôi;)
guneysus

143
def xstr(s):
    return '' if s is None else str(s)

3
Cú pháp này được giới thiệu trong 2.5; đối với các phiên bản trước của Python, bạn có thể sử dụng return s is not None and s or ''.
Ben Trống

8
Tôi sẽ quay lại để nhấn mạnh trường hợp commen hơn: return s if s không phải là ai khác ""
Ber

5
@Ber: Tôi sẽ giữ nguyên như vậy, để tránh tiêu cực kép.
Nikhil Chelliah

8
Đây là một ví dụ tốt về cách .. and .. or ..thất bại và tại sao if-other được ưa thích. Có hai lỗi tinh vi trong s is not None and s or ''.

1
return '' if not s else str(s)
Iqbal

106

Có lẽ ngắn nhất sẽ là str(s or '')

Bởi vì Không có sai và "x hoặc y" trả về y nếu x sai. Xem Toán tử Boolean để được giải thích chi tiết. Nó ngắn, nhưng không rõ ràng lắm.


1
điều này thật tuyệt vời, cảm ơn bạn Không bao giờ nghĩ đến việc sử dụng ortheo cách này
user25064

15
Điều này không có tác dụng nếu slà 0, False, hoặc bất kỳ giá trị falsy
wisbucky

4
Chà, điều đó không được đề cập trong yêu cầu của op, vì vậy tôi không thấy quan điểm của bạn ở đây.
dorvak

2
@dorvak OP khá rõ ràng về yêu cầu đầu ra phải là ''iff s is None. Tất cả các đầu vào khác sẽ trở lại s(hoặc str(s)trong yêu cầu sửa đổi).
StvnW

2
@fortea: không hoạt động. Nếu sNone, kết quả của xstr()nên là một chuỗi rỗng, nhưng str(None)đưa ra chuỗi "None", đó là những gì được trả về (vì chuỗi "None"không phải là giá trị giả.
dreamlax

97

Nếu bạn biết rằng giá trị sẽ luôn là một chuỗi hoặc Không có:

xstr = lambda s: s or ""

print xstr("a") + xstr("b") # -> 'ab'
print xstr("a") + xstr(None) # -> 'a'
print xstr(None) + xstr("b") # -> 'b'
print xstr(None) + xstr(None) # -> ''

1
cho đến nay các pythonic nhất. Sử dụng thực tế là python coi Không, danh sách trống, chuỗi rỗng, 0, v.v là sai. Cũng sử dụng thực tế là câu lệnh hoặc trả về phần tử đầu tiên là đúng hoặc phần tử cuối cùng được cung cấp cho hoặc (hoặc nhóm ors). Ngoài ra điều này sử dụng các chức năng lambda. Tôi sẽ cung cấp cho bạn +10 nhưng rõ ràng nó sẽ không cho phép tôi.
Matt

11
Điều này sẽ chuyển đổi 0 và Sai (và bất cứ điều gì khác đánh giá thành Sai khi được chuyển sang bool ())
Arkady

9
Tôi không nghĩ đó là "xa nhất là pythonic". Đó là một thành ngữ phổ biến trong các ngôn ngữ khác và tôi không nghĩ sử dụng nó trong Python là sai, nhưng các biểu thức có điều kiện được giới thiệu chính xác để tránh các thủ thuật như thế này.
Roberto Bonvallet

2
Điều này làm cho [], {}v.v. cho kết quả giống như None, điều không mong muốn. xstr(False), đặc biệt, nên được "False"thay vì "". Lạm dụng lambdas làm cho một ví dụ nghèo nàn, sử dụng def xstr(s): return s or ""ir bạn muốn giữ tất cả trên một dòng.

5
Lưu ý rằng tôi đã đủ điều kiện trả lời ngay từ đầu bằng "Nếu bạn biết rằng giá trị sẽ luôn là một chuỗi hoặc Không".
Vinay Sajip

59

return s or '' sẽ làm việc tốt chỉ cho vấn đề đã nêu của bạn!


4
Đáng lưu ý rằng điều này sẽ cho kết quả khác khi s là Sai hoặc 0 (không phải là câu hỏi chuỗi gốc, nhưng là câu hỏi được cập nhật.)
Oddthinking

@Oddthinking s = Falsehoặc s = 0rất có thể là trường hợp cạnh trong việc sử dụng và có thể dễ dàng giảm nhẹ bằng cách viết nó dưới dạngreturn str(s or '')
Willem van Ketwich

@WillemvanKetwich: Điều đó có cùng một vấn đề: s (Sai) sẽ trả về 'Sai', không phải ''. s (0) sẽ trả về '0', không phải ''. Tương tự như vậy đối với một đối tượng xác định __bool__ hoặc __nonzero__.
Oddthinking

@Oddthinking Tôi thấy quan điểm của bạn. Trong mọi trường hợp, nếu nó được sử dụng riêng cho các đối tượng chuỗi như trong câu hỏi của OP thì đó không phải là vấn đề.
Willem van Ketwich

@WillemvanKetwich: Hãy xem câu hỏi được cập nhật và cảnh báo trong nhận xét của tôi - điều này đã được đề cập,
Oddthinking

14
def xstr(s):
   return s or ""

4
Lợi nhuận này ''cho 0, [], {}, Falsevà giả như giá trị, mà không phải là những gì người đăng yêu cầu.
StvnW

1
chỉ cần đặt str ([...]) xung quanh s: def xstr(s): return str(s) or ""
Federico Simonetta

8

Cách chức năng (một lớp lót)

xstr = lambda s: '' if s is None else s

1
"def xstr (s): return '' if s is none other s" cũng là một on-liner, python không nghiêm ngặt với các khoảng trắng sau tất cả
SilentGhost

2
Nó không phải là một lớp lót thực sự, nó chỉ được viết bằng một dòng g
Dario

1
Theo nghĩa nào thì nó không phải là một người di chuyển thực sự? kiểm tra thông dịch viên của bạn - đó không phải là lỗi cú pháp. cho tất cả ý định và mục đích, nó thực sự hơn lambda ^ _ ^
SilentGhost

2
PEP 8 loài mà bạn nên sử dụng def thay vì gán lambda cho một biến. Ưu điểm thực sự duy nhất của lambda là bạn có thể viết như một phần của biểu thức (chẳng hạn chuyển sang hàm khác) và lợi thế đó bị mất trong mã như thế này. Tôi cũng đã từng làm điều này, cho đến khi tôi nhận thấy rằng def có thể được viết thành một dòng, và sau đó PEP 8 chỉ cho tôi con đường để đi. LUÔN LUÔN theo các vị thần trăn.
Guy

8

Một lớp lót gọn gàng để thực hiện tòa nhà này trên một số câu trả lời khác:

s = (lambda v: v or '')(a) + (lambda v: v or '')(b)

hoặc thậm chí chỉ:

s = (a or '') + (b or '')

Tại sao thậm chí đề cập đến (lambda v: v or '')?
Tvde1

Tại sao không? 2 lời khuyên cho giá của 1! 😀
Willem van Ketwich

1
Xin lưu ý rằng Falsevà danh sách trống cũng sẽ được chuyển thành ''.
Nik O'Lai

tương tự 0, v.v.
Walter Tross

6
def xstr(s):
    return {None:''}.get(s, s)

Tôi nghĩ, nó khá là pythonic - làm thế nào về cái này: "xstr = lambda s: {Không: ''}. Get (s, s)" - giảm toàn bộ điều xuống một lớp lót.
Juergen

14
Chậm không cần thiết (xây dựng và tra cứu thêm), và khó đọc hơn. Khá unpythonic.
Triptych

Bạn đúng. Nó khá là hoàn hảo nhưng nó tránh được một bước nhảy có điều kiện trong mã byte của python.
tobidope

4
Lệnh gọi hàm get () ngụ ý ít nhất một bước nhảy có điều kiện bổ sung.
Triptych

1
Tôi sẽ không thể nói những gì nên làm mà không biết câu hỏi hoặc tìm kiếm get.
Dario

5

Tôi sử dụng chức năng tối đa:

max(None, '')  #Returns blank
max("Hello",'') #Returns Hello

Hoạt động như một bùa mê;) Chỉ cần đặt chuỗi của bạn vào tham số đầu tiên của hàm.


5
Điều này hoạt động vì 'str'> 'noneType' và là đặc trưng của CPython. Từ hướng dẫn : "Các đối tượng thuộc các loại khác nhau ngoại trừ số được sắp xếp theo tên loại của chúng". Ngoài ra, điều này sẽ không hoạt động trong Python 3000, vì so sánh giữa các loại không còn được phép (TypeError: các loại không thể sắp xếp: str ()> noneType ()). Xem Python so sánh chuỗi và int như thế nào?
plok

Rất tốt để biết cảm ơn, vì vậy không phải là một ý tưởng tốt để tiến lên với mã tương thích python 3.x.
radtek

4

Biến thể ở trên nếu bạn cần tương thích với Python 2.4

xstr = lambda s: s is not None and s or ''

2

Nếu đó là về định dạng chuỗi, bạn có thể làm như sau:

from string import Formatter

class NoneAsEmptyFormatter(Formatter):
    def get_value(self, key, args, kwargs):
        v = super().get_value(key, args, kwargs)
        return '' if v is None else v

fmt = NoneAsEmptyFormatter()
s = fmt.format('{}{}', a, b)

1
def xstr(s):
    return s if s else ''

s = "%s%s" % (xstr(a), xstr(b))

5
Điều này sẽ trả về một chuỗi trống cho tất cả các giá trị giống như sai, đó không phải là những gì người đăng yêu cầu.
Triptych

1

Chúng ta luôn có thể tránh việc truyền kiểu trong các tình huống được giải thích dưới đây.

customer = "John"
name = str(customer)
if name is None
   print "Name is blank"
else: 
   print "Customer name : " + name

Trong ví dụ trên, trong trường hợp giá trị của khách hàng là không có giá trị, nó sẽ tiếp tục được truyền trong khi được gán cho 'name'. Việc so sánh trong mệnh đề 'if' sẽ luôn thất bại.

customer = "John" # even though its None still it will work properly.
name = customer
if name is None
   print "Name is blank"
else: 
   print "Customer name : " + str(name)

Ví dụ trên sẽ hoạt động đúng. Các kịch bản như vậy rất phổ biến khi các giá trị đang được tìm nạp từ URL, JSON hoặc XML hoặc thậm chí các giá trị cần thêm kiểu truyền cho bất kỳ thao tác nào.


0

Sử dụng đánh giá ngắn mạch:

s = a or '' + b or ''

Vì + không phải là một hoạt động rất tốt trên chuỗi, nên sử dụng chuỗi định dạng tốt hơn:

s = "%s%s" % (a or '', b or '')

2
Điều này cũng sẽ chuyển đổi 'a' thành chuỗi rỗng cho tất cả các giá trị giống như sai, không chỉ là Không có. Chẳng hạn, các bộ dữ liệu, danh sách và ký tự trống sẽ chuyển đổi thành các chuỗi trống, đây không phải là những gì OP chỉ định.
Triptych

+là một toán tử hoàn toàn tốt cho hai chuỗi. Đó là khi bạn cố gắng sử dụng nó để tham gia hàng tá mà bạn gặp khó khăn. Đối với hai người, nó có thể sẽ nhanh hơn các tùy chọn khác; dù bằng cách nào, đó là trong tiếng ồn.
kquinn

+1 đối với tôi vì đây chính xác là những gì tôi cần trong trường hợp của mình: lambda hoặc chức năng thay thế một toán tử duy nhất ( or) có vẻ hơi quá mức đối với tôi ... Tôi không có trường hợp nào có giá trị sai lệch khác - kể cả str hoặc Không. Khác với nhận xét về +nhà điều hành, có thể phụ thuộc vào kịch bản cụ thể và có thể cần điểm chuẩn, câu trả lời này không xứng đáng với -1
đô thị

-3

Sử dụng chuỗi F nếu bạn đang sử dụng python v3.7

xstr = F"{s}"

1
Điều này là sai và trả về chuỗi 'None'nếu sNone.
Lawrence
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.