Jak podzielić ciąg na tablicę znaków?


450

Próbowałem rozejrzeć się w Internecie w poszukiwaniu odpowiedzi na podział łańcucha na tablicę znaków, ale nie mogę znaleźć prostej metody

str.split(//)nie działa tak jak Ruby. Czy istnieje prosty sposób na zrobienie tego bez zapętlania?


12
W Pythonie łańcuchy są już tablicami znaków do wszystkich celów oprócz zamiany. Możesz je pokroić, odwołać lub wyszukać przedmioty według indeksu itp.
dansalmo,

Odpowiedzi:


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

Potrzebujesz listy


2
Moim zdaniem znacznie lepiej niż metoda ruby, możesz swobodnie konwertować między typami sekwencji, jeszcze lepiej, na poziomie C.
arthurprs

Konstruktor list to elegancka funkcja, która automatycznie konwertuje ciąg znaków na tablicę znaków. Ponieważ String jest jednorodną sekwencją znaków Unicode, fajnie jest pracować z Pythonem, a twórca Guido sprawił, że jest lepszy. Kochający python ze względu na jego wspaniałe możliwości.
Doogle,

Chcę tutaj flagi, aby tego nie robić ... ale w każdym razie, jeśli chcesz wywoływać, możesz uniknąć tego zachowania za pomocącast_method = lambda x: [x]
madzohan


60

Możesz to zrobić w bardzo prosty sposób bez list ():

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

4
Witamy w Stackoverflow. Czy mógłbyś trochę rozszerzyć odpowiedź, aby wyjaśnić, w jaki sposób rozwiązuje problem?
NJInamdar

21
To jest po prostu for, nie ma wiele do wyjaśnienia. Myślę, że powinieneś przeczytać samouczek Pythona na temat struktur danych , zwłaszcza listy.
WhyNotHugo,

4
To po prostu oznacza list(map(lambda c: c, iter("foobar"))), ale bardziej czytelne i znaczące.
no1xsyzy 12.12.17

41

Jeśli chcesz przetwarzać swój ciąg po jednym znaku na raz. masz różne opcje.

uhello = u'Hello\u0020World'

Korzystanie ze zrozumienia listy:

print([x for x in uhello])

Wynik:

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

Korzystanie z mapy:

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

Wynik:

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

Wywołanie Funkcja wbudowanej listy:

print(list(uhello))

Wynik:

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

Korzystanie z pętli for:

for c in uhello:
    print(c)

Wynik:

H
e
l
l
o

W
o
r
l
d

Czy istnieją różnice w charakterystyce wydajności każdej z tych metod?
qxzsilver

20

Zbadałem kolejne dwa sposoby realizacji tego zadania. Może to być pomocne dla kogoś.

Pierwszy jest łatwy:

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

A drugi użycie mapi lambdafunkcja. Może być odpowiedni do bardziej złożonych zadań:

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

Na przykład

# 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', '', '']

Zobacz dokumentację Pythona, aby uzyskać więcej metod


Pierwszy sposób jest bardzo prosty. Czy istnieją powody, dla których ludzie chcieliby czegoś bardziej złożonego?
undrline

Dzień dobry! Pierwsza opcja jest rzeczywiście prosta. Drugi ma jednak lepszy potencjał do obsługi bardziej złożonego przetwarzania.
Aleksiej Milogradow

19

Zadanie sprowadza się do iteracji znaków w łańcuchu i zebrania ich na listę. Tak wyglądałoby najbardziej naiwne rozwiązanie

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

Oczywiście można go skrócić do sprawiedliwego

result = [character for character in string]

ale wciąż istnieją krótsze rozwiązania, które robią to samo.

listkonstruktor może być użyty do konwersji dowolnej iterowalnej (iteratory, listy, krotki, łańcuch itp.) na listę.

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

Dużym plusem jest to, że działa tak samo w Pythonie 2 i Pythonie 3.

Począwszy od Python 3.5 (dzięki niesamowitemu PEP 448 ) można teraz zbudować listę z dowolnej iteracji poprzez rozpakowanie jej na pusty literał listy:

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

Jest to starsze, aw niektórych przypadkach bardziej wydajne niż listbezpośrednie wywoływanie konstruktora.

Radzę przed użyciem mapopartych podejścia, ponieważ mapnie nie zwróci listę w Pythonie 3. Patrz , jak filtrować użytkowania, mapy, i zmniejszyć w Pythonie 3 .


Myślę, że ostatnia propozycja jest bardzo fajna. Ale nie rozumiem, dlaczego ponownie zapoznałeś się z niektórymi innymi podejściami (większość z nich) już tu opublikowano i odwracasz uwagę od niesamowitego rozwiązania python 3.5!
MSeifert,

14

Potrzebuję tylko szeregu znaków:

arr = list(str)

Jeśli chcesz podzielić str przez określony str:

# str = "temp//temps" will will be ['temp', 'temps']
arr = str.split("//")

12

split()wbudowana funkcja rozdzieli wartość tylko na podstawie określonego warunku, ale w jednym słowie nie może spełnić warunku. Można to rozwiązać za pomocąlist() . Wewnętrznie wywołuje tablicę i przechowuje wartość na podstawie tablicy.

Przypuszczać,

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

Jeśli chcesz czytać tylko dostęp do ciągu, możesz bezpośrednio użyć notacji tablicowej.

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'

Może być przydatny do testowania bez użycia wyrażenia regularnego. Czy ciąg zawiera końcowy znak nowej linii?

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

1

Cóż, tak jak lubię wersję list (y), oto kolejny bardziej szczegółowy sposób, w jaki znalazłem (ale jest fajny, więc pomyślałem, że dodam go do walki):

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

podobnie jak, list(string)ale zwraca generator leniwie oceniany w punkcie użytkowania, dzięki czemu pamięć jest wydajna.


Nie jestem pewien, gdzie byłoby to bardziej przydatne niż sam ciąg, który można iterować.
Ry-

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

gdzie a to ciąg, który chcesz oddzielić. Wartości „a [i]” to indywidualny znak ciągu, który można dołączyć do listy.


1
for c in a: print cjest o wiele bardziej bezpośredni
James Waldby - jwpat7
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.