Python string.join (list) trên mảng đối tượng chứ không phải mảng chuỗi


291

Trong Python, tôi có thể làm:

>>> list = ['a', 'b', 'c']
>>> ', '.join(list)
'a, b, c'

Có cách nào dễ dàng để làm điều tương tự khi tôi có một danh sách các đối tượng không?

>>> class Obj:
...     def __str__(self):
...         return 'name'
...
>>> list = [Obj(), Obj(), Obj()]
>>> ', '.join(list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, instance found

Hay tôi phải dùng đến một vòng lặp for?

Câu trả lời:


432

Bạn có thể sử dụng một sự hiểu biết danh sách hoặc một biểu thức trình tạo thay thế:

', '.join([str(x) for x in list])  # list comprehension
', '.join(str(x) for x in list)    # generator expression

3
hoặc một biểu thức trình tạo: ',' .join (str (x) cho x trong danh sách)
dF.

1
bất kỳ ý tưởng về cái nào trong số họ sẽ nhanh hơn?
gozzilli

Các thí nghiệm của tôi nói rằng khả năng hiểu danh sách có thể nhanh hơn 60% trong các danh sách nhỏ (thử nghiệm chạy 10 ^ 6 lần trong danh sách ba đối tượng () s). Tuy nhiên, hiệu suất của chúng tương tự trên các danh sách lớn (thử nghiệm thứ 2 chạy một lần trên danh sách 10 ^ 7 đối tượng ()).
gozzilli

3
để tăng tốc 30% tốt (biểu thức trên trình tạo ở trên), người ta có thể sử dụng mapbiểu thức được cho là ít đọc hơn (bên dưới).
K3 --- rnc

2
Câu trả lời này là khách quan tồi tệ hơn mapgiải pháp.
PascalVKooten

96

Trình xây dựng chuỗi tích hợp sẽ tự động gọi obj.__str__:

''.join(map(str,list))

1
map () không thay đổi danh sách, nó tương đương với [str (o) cho o trong danh sách]
dF.

11
+1: Bản đồ là một cách tiếp cận tốt; "Thay đổi danh sách" không phải là một nhận xét chính xác.
S.Lott

2
(khác) +1 .. bản đồ không thể đọc được, chỉ cần biết chức năng bản đồ làm gì
lapax

1
@Michael Không đúng. reducelà cái đã bị loại bỏ, bởi vì nó thường khiến mọi người đoán và do đó không phải là "pythonic". mapmặt khác không phải là một vấn đề.
PascalVKooten

1
(khác) +1: đến từ thế giới Perl, đây là điều phổ biến nhất trong vũ trụ: tham gia ("sep", danh sách) - và tất cả các yếu tố của danh sách được chuyển đổi thành biểu diễn chuỗi của chúng. Tôi đã thực sự vật lộn để tìm một giải pháp trong trăn.
Jason

2

một giải pháp khác là ghi đè toán tử nối của lớp str.

Hãy để chúng tôi định nghĩa một lớp mới my_ chuỗi như sau

class my_string(str):
    def join(self, l):
        l_tmp = [str(x) for x in l]
        return super(my_string, self).join(l_tmp)

Sau đó bạn có thể làm

class Obj:
    def __str__(self):
        return 'name'

list = [Obj(), Obj(), Obj()]
comma = my_string(',')

print comma.join(list)

và bạn nhận được

name,name,name

BTW, bằng cách sử dụng danh sách làm tên biến, bạn đang xác định lại lớp danh sách (từ khóa)! Tốt nhất là sử dụng tên định danh khác.

Hy vọng bạn sẽ tìm thấy câu trả lời của tôi hữu ích.


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.