จะแบ่งสตริงออกเป็นอาร์เรย์ของอักขระได้อย่างไร


451

ฉันพยายามค้นหาคำตอบในการแยกสตริงออกเป็นชุดอักขระ แต่ฉันไม่สามารถหาวิธีง่าย ๆ ได้

str.split(//)ดูเหมือนจะไม่ทำงานเหมือนทับทิม มีวิธีง่ายๆในการทำเช่นนี้โดยไม่วนซ้ำหรือไม่?


12
ใน Python สตริงเป็นอาร์เรย์ของตัวละครอยู่แล้วเพื่อวัตถุประสงค์ทั้งหมดยกเว้นการแทนที่ คุณสามารถ
เชย

คำตอบ:


861
>>> s = "foobar"
>>> list(s)
['f', 'o', 'o', 'b', 'a', 'r']

คุณต้องการรายการ


2
ในความคิดของฉันดีกว่าวิธีทับทิมคุณสามารถแปลงระหว่างประเภทลำดับได้อย่างอิสระดีขึ้นในระดับ C
arthurprs

รายการคอนสตรัคเตอร์เป็นคุณสมบัติที่สวยงามซึ่งจะแปลงสตริงเป็นอาเรย์ตัวอักษรโดยอัตโนมัติ เนื่องจาก String เป็นลำดับที่เหมือนกันของตัวละครยูนิโค้ดมันเจ๋งมากที่ได้ทำงานกับ Python และผู้สร้าง Guido ทำให้ดีขึ้น รักหลามสำหรับความสามารถที่ยอดเยี่ยม
Doogle

ฉันต้องการธงที่นี่เพื่อไม่ทำเช่นนี้ ... แต่อย่างไรก็ตามถ้าคุณต้องการ callable คุณสามารถหลบหนีปัญหานี้โดยใช้cast_method = lambda x: [x]
madzohan


61

คุณสามารถทำได้ด้วยวิธีง่ายๆโดยไม่ต้องมีรายการ ():

>>> [c for c in "foobar"]
['f', 'o', 'o', 'b', 'a', 'r']

4
ยินดีต้อนรับสู่ stackoverflow คุณช่วยขยายคำตอบเล็กน้อยเพื่ออธิบายวิธีแก้ปัญหาได้ไหม
NJInamdar

21
นี่เป็นเพียงแค่forมีไม่มากที่จะอธิบาย ฉันคิดว่าคุณควรอ่านบทช่วยสอนเกี่ยวกับโครงสร้างข้อมูลโดยเฉพาะรายการความเข้าใจ
WhyNotHugo

4
นี่หมายถึงlist(map(lambda c: c, iter("foobar")))แต่อ่านได้และมีความหมายมากกว่า
no1xsyzy

42

หากคุณต้องการประมวลผลสตริงของคุณหนึ่งตัวอักษรในเวลา คุณมีตัวเลือกต่าง ๆ

uhello = u'Hello\u0020World'

ใช้รายการเข้าใจ:

print([x for x in uhello])

เอาท์พุท:

['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']

ใช้แผนที่:

print(list(map(lambda c2: c2, uhello)))

เอาท์พุท:

['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']

ฟังก์ชั่นการโทรในตัวรายการ:

print(list(uhello))

เอาท์พุท:

['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']

ใช้สำหรับวง:

for c in uhello:
    print(c)

เอาท์พุท:

H
e
l
l
o

W
o
r
l
d

ลักษณะของประสิทธิภาพการทำงานของแต่ละวิธีมีความแตกต่างกันหรือไม่?
qxzsilver

20

ฉันสำรวจอีกสองวิธีเพื่อให้งานนี้สำเร็จ มันอาจจะเป็นประโยชน์สำหรับใครบางคน

คนแรกนั้นง่าย:

In [25]: a = []
In [26]: s = 'foobar'
In [27]: a += s
In [28]: a
Out[28]: ['f', 'o', 'o', 'b', 'a', 'r']

และการใช้ครั้งที่สองmapและlambdaฟังก์ชั่น อาจเหมาะสมสำหรับงานที่ซับซ้อนมากขึ้น:

In [36]: s = 'foobar12'
In [37]: a = map(lambda c: c, s)
In [38]: a
Out[38]: ['f', 'o', 'o', 'b', 'a', 'r', '1', '2']

ตัวอย่างเช่น

# isdigit, isspace or another facilities such as regexp may be used
In [40]: a = map(lambda c: c if c.isalpha() else '', s)
In [41]: a
Out[41]: ['f', 'o', 'o', 'b', 'a', 'r', '', '']

ดูpython docsสำหรับวิธีการเพิ่มเติม


วิธีแรกนั้นง่ายมาก มีเหตุผลที่ผู้คนต้องการบางสิ่งที่ซับซ้อนกว่านี้ไหม?
ยกเลิกการจัดวาง

สวัสดี! ตัวเลือกแรกนั้นง่ายจริงๆ อย่างไรก็ตามอันที่สองนั้นมีศักยภาพที่ดีกว่าสำหรับการจัดการกับการประมวลผลที่ซับซ้อนมากขึ้น
Alexey Milogradov

19

งานจะทำการวนซ้ำของอักขระในสตริงและรวบรวมลงในรายการ วิธีการแก้ปัญหาไร้เดียงสามากที่สุดจะมีลักษณะ

result = []
for character in string:
    result.append(character)

แน่นอนว่ามันสามารถย่อให้เหลือเพียง

result = [character for character in string]

แต่ยังมีวิธีแก้ปัญหาที่สั้นกว่าที่ทำในสิ่งเดียวกัน

listคอนสตรัคสามารถใช้ในการแปลงใด ๆiterable (iterators, รายการ, tuples, สตริง ฯลฯ ) เพื่อรายการ

>>> list('abc')
['a', 'b', 'c']

ข้อดีคือมันใช้งานได้ทั้งใน Python 2 และ Python 3

นอกจากนี้เริ่มจาก Python 3.5 (ด้วยPEP 448 ที่ยอดเยี่ยม ) ตอนนี้เป็นไปได้ที่จะสร้างรายการจากการทำซ้ำได้โดยการแกะมันออกเป็นรายการที่ว่างเปล่า:

>>> [*'abc']
['a', 'b', 'c']

นี่คือ neater และในบางกรณีมีประสิทธิภาพมากกว่าการเรียกlistconstructor โดยตรง

ผมแนะนำให้กับการใช้mapวิธีชั่นเพราะmapไม่ได้กลับรายการในหลาม 3. ดูวิธีการกรองการใช้แผนที่และลดในหลาม 3


ฉันคิดว่าข้อเสนอสุดท้ายนั้นดีมาก แต่ฉันไม่เห็นว่าทำไมคุณถึงวิธีการอื่น ๆ (ส่วนใหญ่) ได้โพสต์ที่นี่แล้วและหันเหความสนใจจากโซลูชันงูหลาม 3.5 ที่น่าทึ่ง !
MSeifert


12

split()ฟังก์ชั่น inbuilt จะแยกเฉพาะค่าตามเงื่อนไขบางอย่าง แต่ในคำเดียวมันไม่สามารถปฏิบัติตามเงื่อนไข list()ดังนั้นจึงจะสามารถแก้ไขได้ด้วยความช่วยเหลือของ มันเรียก Array ภายในและจะเก็บค่าไว้บนพื้นฐานของอาเรย์

สมมติ,

a = "bottle"
a.split() // will only return the word but not split the every single char.

a = "bottle"
list(a) // will separate ['b','o','t','t','l','e']


3

หากคุณต้องการอ่านเฉพาะการเข้าถึงสตริงคุณสามารถใช้รูปแบบอาร์เรย์ได้โดยตรง

Python 2.7.6 (default, Mar 22 2014, 22:59:38) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> t = 'my string'
>>> t[1]
'y'

อาจเป็นประโยชน์สำหรับการทดสอบโดยไม่ต้องใช้ regexp สตริงมีการขึ้นบรรทัดใหม่ที่สิ้นสุดหรือไม่?

>>> t[-1] == '\n'
False
>>> t = 'my string\n'
>>> t[-1] == '\n'
True

1

ดีมากเท่าที่ฉันชอบเวอร์ชันรายการนี่เป็นอีกวิธีหนึ่งที่ฉันพบ (แต่มันเจ๋งฉันเลยคิดว่าฉันจะเพิ่มมันเข้าไปในการต่อสู้):

>>> text = "My hovercraft is full of eels"
>>> [text[i] for i in range(len(text))]
['M', 'y', ' ', 'h', 'o', 'v', 'e', 'r', 'c', 'r', 'a', 'f', 't', ' ', 'i', 's', ' ', 'f', 'u', 'l', 'l', ' ', 'o', 'f', ' ', 'e', 'e', 'l', 's']

camelcase = ''.join([text[i].upper() if i % 2 else text[i].lower() for i in range(len(text))])
whereisalext

1
from itertools import chain

string = 'your string'
chain(string)

คล้ายกับlist(string)แต่ส่งคืนตัวกำเนิดที่ประเมินอย่างเฉื่อยชา ณ จุดใช้งานดังนั้นหน่วยความจำจึงมีประสิทธิภาพ


ไม่แน่ใจว่าสิ่งนี้จะมีประโยชน์มากกว่าตัวสตริงเองหรือไม่ซึ่งสามารถทำซ้ำได้
Ry-

0
>>> for i in range(len(a)):
...     print a[i]
... 

โดยที่ a คือสตริงที่คุณต้องการแยกออก ค่า "a [i]" เป็นอักขระแต่ละตัวของสตริงซึ่งสามารถผนวกเข้ากับรายการ


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