IT박스

파이썬에서 빈 문자열을 분할 할 때 split ( '\ n')이 [ '']를 반환하는 동안 split ()이 빈 목록을 반환하는 이유는 무엇입니까?

itboxs 2020. 6. 26. 19:05
반응형

파이썬에서 빈 문자열을 분할 할 때 split ( '\ n')이 [ '']를 반환하는 동안 split ()이 빈 목록을 반환하는 이유는 무엇입니까?


split('\n')하나의 문자열로 줄을 가져 오는 데 사용 하고 ''.split()있으며 빈 목록 반환하는 []반면을 ''.split('\n')반환합니다 ['']. 그러한 차이에 대한 특별한 이유가 있습니까?

그리고 문자열에서 줄을 계산하는 더 편리한 방법이 있습니까?


질문 : split ( '\ n')을 사용하여 한 문자열로 줄을 가져오고 ''.split ()이 빈 목록 []을 반환하는 반면 ''.split ( '\ n')은 [ '']를 반환한다는 것을 알았습니다. .

str.split () 메소드는 두 알고리즘을 갖는다. 인수가 제공되지 않으면 반복 된 공백 실행으로 분할됩니다. 그러나 인수가 제공되면 반복 실행없이 단일 분리 문자로 처리됩니다.

빈 문자열을 분할하는 경우 첫 번째 모드 (인수 없음)는 공백이 먹고 결과 목록에 입력 할 값이 없기 때문에 빈 목록을 반환합니다.

반대로 두 번째 모드 (와 같은 인수 사용 \n)는 첫 번째 빈 필드를 생성합니다. 작성 '\n'.split('\n')했다면 두 개의 필드를 얻을 것입니다 (하나의 분할, 두 개의 반쪽 제공).

질문 : 그러한 차이에 대한 특별한 이유가 있습니까?

이 첫 번째 모드는 가변적 인 양의 공백이있는 열에서 데이터를 정렬 할 때 유용합니다. 예를 들면 다음과 같습니다.

>>> data = '''\
Shasta      California     14,200
McKinley    Alaska         20,300
Fuji        Japan          12,400
'''
>>> for line in data.splitlines():
        print line.split()

['Shasta', 'California', '14,200']
['McKinley', 'Alaska', '20,300']
['Fuji', 'Japan', '12,400']

두 번째 모드는 반복되는 쉼표가 빈 필드를 나타내는 CSV와 같은 구분 된 데이터에 유용합니다. 예를 들면 다음과 같습니다.

>>> data = '''\
Guido,BDFL,,Amsterdam
Barry,FLUFL,,USA
Tim,,,USA
'''
>>> for line in data.splitlines():
        print line.split(',')

['Guido', 'BDFL', '', 'Amsterdam']
['Barry', 'FLUFL', '', 'USA']
['Tim', '', '', 'USA']

결과 필드 수는 분리 문자 수보다 1이 큽니다. 밧줄을 자르는 것을 생각하십시오. 당신이 상처를하지 않으면, 당신은 한 조각이 있습니다. 한 번 잘라 두 조각을 제공합니다. 두 번 자르면 세 조각이 나옵니다. 그리고 그것은 파이썬의 str.split (delimiter) 메소드를 사용합니다 :

>>> ''.split(',')       # No cuts
['']
>>> ','.split(',')      # One cut
['', '']
>>> ',,'.split(',')     # Two cuts
['', '', '']

질문 : 문자열에서 줄을 계산하는 더 편리한 방법이 있습니까?

예, 몇 가지 쉬운 방법이 있습니다. 하나 개의 용도는 str.count () 와 다른 용도의 str.splitlines () . 마지막 줄에이없는 경우를 제외하고 두 가지 방법 모두 동일한 대답을 제공합니다 \n. 마지막 줄 바꿈이 없으면 str.splitlines 접근 방식으로 정확한 답을 얻을 수 있습니다. 정확한 빠른 기술은 count 방법을 사용하지만 최종 줄 바꿈에 맞게 수정합니다.

>>> data = '''\
Line 1
Line 2
Line 3
Line 4'''

>>> data.count('\n')                               # Inaccurate
3
>>> len(data.splitlines())                         # Accurate, but slow
4
>>> data.count('\n') + (not data.endswith('\n'))   # Accurate and fast
4    

Question from @Kaz: Why the heck are two very different algorithms shoe-horned into a single function?

The signature for str.split is about 20 years old, and a number of the APIs from that era are strictly pragmatic. While not perfect, the method signature isn't "terrible" either. For the most part, Guido's API design choices have stood the test of time.

The current API is not without advantages. Consider strings such as:

ps_aux_header  = "USER               PID  %CPU %MEM      VSZ"
patient_header = "name,age,height,weight"

When asked to break these strings into fields, people tend to describe both using the same English word, "split". When asked to read code such as fields = line.split() or fields = line.split(','), people tend to correctly interpret the statements as "splits a line into fields".

Microsoft Excel's text-to-columns tool made a similar API choice and incorporates both splitting algorithms in the same tool. People seem to mentally model field-splitting as a single concept even though more than one algorithm is involved.


It seems to simply be the way it's supposed to work, according to the documentation:

Splitting an empty string with a specified separator returns [''].

If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a None separator returns [].

So, to make it clearer, the split() function implements two different splitting algorithms, and uses the presence of an argument to decide which one to run. This might be because it allows optimizing the one for no arguments more than the one with arguments; I don't know.


.split() without parameters tries to be clever. It splits on any whitespace, tabs, spaces, line feeds etc, and it also skips all empty strings as a result of this.

>>> "  fii    fbar \n bopp ".split()
['fii', 'fbar', 'bopp']

Essentially, .split() without parameters are used to extract words from a string, as opposed to .split() with parameters which just takes a string and splits it.

That's the reason for the difference.

And yeah, counting lines by splitting is not an efficient way. Count the number of line feeds, and add one if the string doesn't end with a line feed.


Use count():

s = "Line 1\nLine2\nLine3"
n_lines = s.count('\n') + 1

>>> print str.split.__doc__
S.split([sep [,maxsplit]]) -> list of strings

Return a list of the words in the string S, using sep as the
delimiter string.  If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are removed
from the result.

Note the last sentence.

To count lines you can simply count how many \n are there:

line_count = some_string.count('\n') + some_string[-1] != '\n'

The last part takes into account the last line that do not end with \n, even though this means that Hello, World! and Hello, World!\n have the same line count(which for me is reasonable), otherwise you can simply add 1 to the count of \n.


To count lines, you can count the number of line breaks:

n_lines = sum(1 for s in the_string if s == "\n") + 1 # add 1 for last line

Edit:

The other answer with built-in count is more suitable, actually

참고URL : https://stackoverflow.com/questions/16645083/when-splitting-an-empty-string-in-python-why-does-split-return-an-empty-list

반응형