Python string.join (รายการ) บนอาร์เรย์วัตถุแทนอาร์เรย์สตริง


291

ใน Python ฉันทำได้:

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

มีวิธีง่าย ๆ ที่จะทำเช่นเดียวกันเมื่อฉันมีรายการวัตถุหรือไม่?

>>> 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

หรือฉันต้องหันไปหาวง?

คำตอบ:


432

คุณสามารถใช้ list comprehension หรือ expression ของตัวสร้างแทน:

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

3
หรือนิพจน์ตัวสร้าง: ',' .join (str (x) สำหรับ x in list)
dF

1
ความคิดใดที่จะเร็วกว่ากัน?
gozzilli

การทดลองของฉันบอกว่ารายการเข้าใจได้เร็วขึ้น 60% ในรายการเล็ก ๆ (ทดลองเรียกใช้ 10 ^ 6 ครั้งในรายการวัตถุสามรายการ) อย่างไรก็ตามประสิทธิภาพการทำงานของพวกเขานั้นใกล้เคียงกับรายการใหญ่ (การทดสอบครั้งที่ 2 ทำงานครั้งเดียวในรายการ 10 ^ 7 วัตถุ ()
gozzilli

3
สำหรับการเร่งความเร็ว 30% ที่ดี (เหนือนิพจน์ตัวสร้างด้านบน) คุณสามารถใช้mapนิพจน์ที่อ่านได้น้อยกว่า(ด้านล่าง)
K3 --- rnc

2
คำตอบนี้เลวร้ายยิ่งกว่าmapวิธีแก้ปัญหา
PascalVKooten

96

ตัวสร้างสตริงในตัวจะเรียกโดยอัตโนมัติobj.__str__:

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

1
แผนที่ () ไม่เปลี่ยนแปลงรายการมันเท่ากับ [str (o) สำหรับ o ในรายการ]
dF

11
+1: แผนที่เป็นวิธีการที่ดี "การเปลี่ยนรายการ" ไม่ใช่ความคิดเห็นที่ถูกต้อง
S.Lott

2
(อื่น) +1 .. แผนที่ไม่สามารถอ่านได้น้อยต้องรู้ว่าฟังก์ชั่นแผนที่ทำอะไรได้บ้าง
lapax

1
@Michael ไม่ถูกต้อง reduceเป็นสิ่งที่ถูกลบเพราะมักจะทำให้ผู้คนคาดเดาและไม่ใช่ "pythonic" mapในขณะที่ไม่มีปัญหา
PascalVKooten

1
(อีก) +1: มาจากโลก Perl นี่เป็นสิ่งที่พบบ่อยที่สุดในจักรวาล: เข้าร่วม ("กันยายน", รายการ) - และองค์ประกอบทั้งหมดของรายการจะถูกแปลงเป็นการแสดงสตริงของพวกเขา ฉันพยายามอย่างมากที่จะหาทางออกในงูใหญ่
เจสัน

2

อีกวิธีคือการแทนที่โอเปอเรเตอร์การเข้าร่วมของคลาส str

ให้เรากำหนดคลาสใหม่ my_string ดังนี้

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

จากนั้นคุณสามารถทำได้

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

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

print comma.join(list)

และคุณจะได้รับ

name,name,name

BTW โดยใช้listเป็นชื่อตัวแปรคุณกำลังกำหนด class list ใหม่ (คีย์เวิร์ด)! ควรใช้ชื่อตัวระบุอื่น

หวังว่าคุณจะพบคำตอบของฉันมีประโยชน์


1

ฉันรู้ว่านี้คือการโพสต์เก่าสุด แต่ผมคิดว่าสิ่งที่จะพลาดจะเอาชนะ__repr__เพื่อที่ว่า__repr__ = __str__ซึ่งเป็นคำตอบที่ได้รับการยอมรับในเรื่องนี้คำถามที่ทำเครื่องหมายไว้ที่ซ้ำกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.