คุณจะสร้างสตริงที่คั่นด้วยเครื่องหมายจุลภาคจากรายการสตริงได้อย่างไร


527

อะไรคือวิธีที่คุณต้องการในการเชื่อมสตริงจากลำดับที่มีการเพิ่มเครื่องหมายจุลภาค นั่นคือคุณทำแผนที่อย่างไร['a', 'b', 'c']เพื่อ'a,b,c'? (กรณี['s']และ[]ควรถูกแมป's'และ''ตามลำดับ)

ฉันมักจะจบลงด้วยการใช้สิ่งที่ชอบ''.join(map(lambda x: x+',',l))[:-1]แต่ก็รู้สึกไม่พอใจบ้าง

คำตอบ:


968
my_list = ['a', 'b', 'c', 'd']
my_string = ','.join(my_list)
'a,b,c,d'

สิ่งนี้จะไม่ทำงานหากรายการมีจำนวนเต็ม


และหากรายการมีประเภทที่ไม่ใช่สตริง (เช่นจำนวนเต็ม, ลอย, bools, ไม่มี) ให้ทำ:

my_string = ','.join(map(str, my_list)) 

หมายเหตุถ้าคุณใช้ python 2.7 (ซึ่งคุณไม่ควรใช้ตอนนี้) การใช้ str จะเพิ่มข้อยกเว้นหากรายการใด ๆ ในรายการมียูนิโค้ด
kroiz

75

ทำไมต้องmap/ lambdaมายากล? มันใช้ไม่ได้เหรอ

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

>>> print(','.join(['a']))
a

ในกรณีที่มีตัวเลขในรายการคุณสามารถใช้ list comprehension:

>>> ','.join([str(x) for x in foo])

หรือนิพจน์ตัวกำเนิด:

>>> ','.join(str(x) for x in foo)

18

",".join(l)จะไม่ทำงานในทุกกรณี ฉันขอแนะนำให้ใช้โมดูล csv กับ StringIO

import StringIO
import csv

l = ['list','of','["""crazy"quotes"and\'',123,'other things']

line = StringIO.StringIO()
writer = csv.writer(line)
writer.writerow(l)
csvcontent = line.getvalue()
# 'list,of,"[""""""crazy""quotes""and\'",123,other things\r\n'

ไม่มีStringIOใน Python 3
Ron Kalian

4
@RonKalian ใช้from io import StringIOใน Python 3
Kevin Ashcraft

13

นี่คือทางเลือกอื่นใน Python 3.0 ซึ่งอนุญาตรายการที่ไม่ใช่สตริง:

>>> alist = ['a', 1, (2, 'b')]
  • วิธีมาตรฐาน

    >>> ", ".join(map(str, alist))
    "a, 1, (2, 'b')"
  • ทางเลือกอื่น

    >>> import io
    >>> s = io.StringIO()
    >>> print(*alist, file=s, sep=', ', end='')
    >>> s.getvalue()
    "a, 1, (2, 'b')"

หมายเหตุ: พื้นที่หลังเครื่องหมายจุลภาคนั้นมีเจตนา


11

คุณไม่ต้องการเพียงแค่:

",".join(l)

เห็นได้ชัดว่ามันซับซ้อนมากขึ้นถ้าคุณต้องการพูด / คอมม่า Escape ในค่าต่างๆ ในกรณีนั้นฉันขอแนะนำให้ดูโมดูล csv ในไลบรารี่มาตรฐาน:

https://docs.python.org/library/csv.html


10

@Peter Hoffmann

การใช้นิพจน์ตัวสร้างมีประโยชน์ในการสร้างตัววนซ้ำ แต่จะบันทึกการนำเข้า itertools นอกจากนี้ความเข้าใจในรายการมักเป็นที่ต้องการในแผนที่ดังนั้นฉันคาดหวังว่านิพจน์เครื่องกำเนิดไฟฟ้าจะได้รับการแนะนำให้ใช้ imap

>>> l = [1, "foo", 4 ,"bar"]
>>> ",".join(str(bit) for bit in l)
'1,foo,4,bar' 

7
>>> my_list = ['A', '', '', 'D', 'E',]
>>> ",".join([str(i) for i in my_list if i])
'A,D,E'

my_listอาจมีตัวแปรประเภทใดก็ได้ 'A,,,D,E'หลีกเลี่ยงปัญหานี้ผลที่ได้


4
l=['a', 1, 'b', 2]

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"

1
ฉันคิดว่าคุณควรชี้ให้เห็นว่าไม่เหมือนกับโซลูชันอื่น ๆ ในหน้านี้คุณพูดสตริงด้วย
mrdevlar

3

@ jmanning2k โดยใช้ความเข้าใจในรายการมีข้อเสียของการสร้างรายการชั่วคราวใหม่ ทางออกที่ดีกว่าคือใช้ itertools.imap ซึ่งส่งคืนตัววนซ้ำ

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))

โซลูชันนี้ไม่ตอบสนองความต้องการในการไม่เพิ่มเครื่องหมายจุลภาคพิเศษสำหรับสตริงว่างและเพิ่ม 'ไม่มี' ด้วย NoneType
Roberto

ตรวจสอบ str.joinทำงานได้เร็วขึ้นlistเมื่อเทียบกับตัวกำเนิด
Grijesh Chauhan

3

นี่คือตัวอย่างของรายการ

>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [i[0] for i in myList])) 
>>> print "Output:", myList
Output: Apple,Orange

แม่นยำยิ่งขึ้น: -

>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [type(i) == list and i[0] for i in myList])) 
>>> print "Output:", myList
Output: Apple,Orange

ตัวอย่างที่ 2: -

myList = ['Apple','Orange']
myList = ','.join(map(str, myList)) 
print "Output:", myList
Output: Apple,Orange

1
คำถามนี้เป็นเรื่องเกี่ยวกับรายการที่ไม่ได้แสดงรายการของรายการ
Eero Aaltonen

@EeroAaltonen ฉันอัพเดตคำตอบของฉันแล้วขอบคุณที่ชี้ให้ฉันเห็นด้วย

1

ฉันจะบอกว่าcsvห้องสมุดเป็นตัวเลือกที่เหมาะสมเท่านั้นที่นี่เพราะมันถูกสร้างขึ้นเพื่อรับมือกับกรณีการใช้งาน csv ทั้งหมดเช่นเครื่องหมายจุลภาคในสตริงเป็นต้น

หากต้องการส่งออกรายการlไปยังไฟล์. csv:

import csv
with open('some.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(l)  # this will output l as a single row.  

นอกจากนี้ยังเป็นไปได้ที่จะใช้writer.writerows(iterable)เพื่อส่งออกหลายแถวไปยัง csv

ตัวอย่างนี้เข้ากันได้กับ Python 3 เนื่องจากคำตอบอื่น ๆ ที่ใช้StringIOคือ Python 2


แต่นั่นก็ไม่ได้ซับซ้อนเกินไปเมื่อเทียบกับคำตอบอื่น ๆ ?
Sreenikethan ฉัน

0

','.join(foo)ควรทำสิ่งที่คุณขอนอกจากว่าฉันขาดอะไร

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

(แก้ไข: และ jmanning2k ชี้ให้เห็น

','.join([str(x) for x in foo])

ปลอดภัยและค่อนข้าง Pythonic แม้ว่าสตริงผลลัพธ์จะเป็นการยากที่จะแยกวิเคราะห์ถ้าองค์ประกอบสามารถมีเครื่องหมายจุลภาค - ณ จุดนั้นคุณต้องการพลังเต็มของcsvโมดูลขณะที่ Douglas ชี้ให้เห็นในคำตอบของเขา)


-2

สองเซ็นต์ของฉัน ฉันชอบรหัสบรรทัดเดียวในไพ ธ อนที่ง่ายขึ้น:

>>> from itertools import imap, ifilter
>>> l = ['a', '', 'b', 1, None]
>>> ','.join(imap(str, ifilter(lambda x: x, l)))
a,b,1
>>> m = ['a', '', None]
>>> ','.join(imap(str, ifilter(lambda x: x, m)))
'a'

มันเป็น pythonic ใช้งานได้กับสตริงตัวเลขไม่มีและสตริงว่าง มันสั้นและตรงตามข้อกำหนด หากรายการไม่ได้มีตัวเลขเราสามารถใช้รูปแบบที่ง่ายกว่านี้:

>>> ','.join(ifilter(lambda x: x, l))

โซลูชันนี้ไม่ได้สร้างรายการใหม่ แต่ใช้ตัววนซ้ำเช่น @Peter Hoffmann แหลม (ขอบคุณ)


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