파이썬의 문자열 목록에서 빈 문자열을 모두 제거하고 싶습니다.
내 생각은 다음과 같습니다.
while '' in str_list:
str_list.remove('')
이 작업을 수행하는 더 파이썬적인 방법이 있습니까?
for var in list:
여기에 글을 썼다 while const in list:
. 어떤 것도 반복하지 않습니다. 조건이 거짓이 될 때까지 동일한 코드를 반복합니다.
파이썬의 문자열 목록에서 빈 문자열을 모두 제거하고 싶습니다.
내 생각은 다음과 같습니다.
while '' in str_list:
str_list.remove('')
이 작업을 수행하는 더 파이썬적인 방법이 있습니까?
for var in list:
여기에 글을 썼다 while const in list:
. 어떤 것도 반복하지 않습니다. 조건이 거짓이 될 때까지 동일한 코드를 반복합니다.
답변:
나는 사용할 것이다 filter
:
str_list = filter(None, str_list)
str_list = filter(bool, str_list)
str_list = filter(len, str_list)
str_list = filter(lambda item: item, str_list)
파이썬 3은에서 반복자를 반환 filter
하므로list()
str_list = list(filter(None, str_list))
itertool
'들ifilter
도 faster-이다 >>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.3468542098999023
; >>> timeit('itertools.ifilter(None, str_list)', 'str_list=["a"]*1000', number=100000)
0.04442191123962402
.
ifilter
결과는 한 번에하지 않고 게으르게 평가 ifilter
됩니다. 대부분의 경우 더 낫습니다. 사용하는 것은 흥미 filter
여전히 빠를 포장보다 ifilter
A의 list
생각.
리스트 이해력을 사용하는 것이 가장 파이썬적인 방법입니다.
>>> strings = ["first", "", "second"]
>>> [x for x in strings if x]
['first', 'second']
업데이트 된 데이터를 확인해야하는 다른 참조가 있으므로 목록을 내부에서 수정해야하는 경우 슬라이스 할당을 사용하십시오.
strings[:] = [x for x in strings if x]
[x for x in strings if x.strip()]
.
filter에는 실제로 다음과 같은 특별한 옵션이 있습니다.
filter(None, sequence)
False로 평가되는 모든 요소를 필터링합니다. bool, len 등과 같은 실제 호출 가능 항목을 사용할 필요가 없습니다.
map (bool, ...)과 동일하게 빠릅니다.
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(None, lstr)
['hello', ' ', 'world', ' ']
시간 비교
>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
4.226747989654541
>>> timeit('filter(None, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.0278358459472656
공지 사항 filter(None, lstr)
공백으로 빈 문자열을 제거하지 않고는 ' '
, 단지 멀리 프 i (prune) ''
동안 ' '.join(lstr).split()
제거합니다 모두.
filter()
공백 문자열을 제거한 상태에서 사용하려면 시간이 더 걸립니다.
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
filter(None, lstr)
공백으로 빈 문자열을 제거하지 않습니다' '
즉 빈 문자열이 아니기 때문에, 그래.
@ Ib33X의 답변은 훌륭합니다. 빈 문자열을 모두 제거하려면 스트립 후 제거하십시오. 스트립 방법도 사용해야합니다. 그렇지 않으면 공백이 있으면 빈 문자열도 반환합니다. ""도 해당 답변에도 유효합니다. 따라서 달성 할 수 있습니다.
strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
이에 대한 답은입니다 ["first", "second"]
.
방법을 대신
사용하려면 filter
다음과 같이하십시오
list(filter(lambda item: item.strip(), strings))
. 이것은 동일한 결과를 제공합니다.
x 대신에 빈 문자열을 제거하기 위해 if X! = ''을 사용합니다. 이처럼 :
str_list = [x for x in str_list if x != '']
이렇게하면 목록에 없음 데이터 형식이 유지됩니다. 또한 목록에 정수가 있고 그 중 하나가 0 인 경우에도 보존됩니다.
예를 들어
str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
str_list = [None, '', 0, "Hi", '', "Hello"]
제대로 디자인되지 않은 응용 프로그램의 표시입니다. 당신은 하지 말았어야 같은 목록에 하나 이상의 인터페이스 (형)과 없음을.
목록의 크기에 따라 새 목록을 만드는 대신 list.remove ()를 사용하는 것이 가장 효율적일 수 있습니다.
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
이것은 새로운 목록을 만들지 않는 장점이 있지만 매번 처음부터 검색해야한다는 단점이 있습니다. while '' in l
위에서 제안한 것과 달리 검색 할 때마다 한 번만 검색하면됩니다 ''
(확실히 최선을 유지할 수있는 방법이 있습니다) 두 가지 방법이지만 더 복잡합니다).
ary[:] = [e for e in ary if e]
. 훨씬 깨끗하고 제어 흐름에 예외를 사용하지 않습니다.
공백을 문자열 안에 유지하려면 일부 접근 방식을 사용하여 실수로 제거 할 수 있습니다. 이 목록이 있다면
[ 'hello world', '', '', 'hello'] 원하는 것 [ 'hello world', 'hello']
먼저 모든 유형의 공백을 빈 문자열로 변환하도록 목록을 자릅니다.
space_to_empty = [x.strip() for x in _text_list]
그런 다음 목록에서 빈 문자열을 제거하십시오.
space_clean_list = [x for x in space_to_empty if x]
space_clean_list = [x.strip() for x in y if x.strip()]
사용 filter
:
newlist=filter(lambda x: len(x)>0, oldlist)
지적한대로 필터를 사용하는 단점은 대안보다 속도가 느리다는 것입니다. 또한,lambda
일반적으로 비용이 많이 듭니다.
또는 가장 단순하고 가장 반복적 인 방법으로 갈 수 있습니다.
# I am assuming listtext is the original list containing (possibly) empty items
for item in listtext:
if item:
newlist.append(str(item))
# You can remove str() based on the content of your original list
이것은 가장 직관적 인 방법이며 적절한 시간 안에 수행합니다.
lambda x: len(x)
나쁜 것보다 나쁩니다 lambda x : x
. 올바른 기능이 바람직하지만 충분하지는 않습니다. downvote 버튼 위에 커서를 놓으면 "이 답변은 유용하지 않습니다"라고 표시됩니다.
Aziz Alto 가보고 한 것처럼 filter(None, lstr)
공백이있는 빈 문자열을 제거하지는 않지만 ' '
lstr에 문자열 만 포함되어 있다고 확신하면 사용할 수 있습니다filter(str.strip, lstr)
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(str.strip, lstr)
['hello', 'world']
내 PC의 시간 비교
>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.356455087661743
>>> timeit('filter(str.strip, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
5.276503801345825
''
공백 ' '
이 있는 문자열 을 제거 하고 비우는 가장 빠른 솔루션 은 남아 있습니다 ' '.join(lstr).split()
.
주석에보고 된 것처럼 문자열에 공백이 있으면 상황이 다릅니다.
>>> lstr = ['hello', '', ' ', 'world', ' ', 'see you']
>>> lstr
['hello', '', ' ', 'world', ' ', 'see you']
>>> ' '.join(lstr).split()
['hello', 'world', 'see', 'you']
>>> filter(str.strip, lstr)
['hello', 'world', 'see you']
당신은 것을 알 수 있습니다 filter(str.strip, lstr)
거기에 공백이 포함 된 문자열을 유지하지만, ' '.join(lstr).split()
이 문자열을 분할합니다.
join
솔루션 을보고 문자열을 공백으로 분할하지만 필터는 분할하지 않습니다. 답변을 개선했습니다.
즉, 모든 공백 문자열이 유지됩니다.
slist = list(filter(None, slist))
프로 :
slist = ' '.join(slist).split()
프로 :
slist = list(filter(str.strip, slist))
프로 :
## Build test-data
#
import random, string
nwords = 10000
maxlen = 30
null_ratio = 0.1
rnd = random.Random(0) # deterministic results
words = [' ' * rnd.randint(0, maxlen)
if rnd.random() > (1 - null_ratio)
else
''.join(random.choices(string.ascii_letters, k=rnd.randint(0, maxlen)))
for _i in range(nwords)
]
## Test functions
#
def nostrip_filter(slist):
return list(filter(None, slist))
def nostrip_comprehension(slist):
return [s for s in slist if s]
def strip_filter(slist):
return list(filter(str.strip, slist))
def strip_filter_map(slist):
return list(filter(None, map(str.strip, slist)))
def strip_filter_comprehension(slist): # waste memory
return list(filter(None, [s.strip() for s in slist]))
def strip_filter_generator(slist):
return list(filter(None, (s.strip() for s in slist)))
def strip_join_split(slist): # words without(!) spaces
return ' '.join(slist).split()
## Benchmarks
#
%timeit nostrip_filter(words)
142 µs ± 16.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit nostrip_comprehension(words)
263 µs ± 19.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter(words)
653 µs ± 37.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_map(words)
642 µs ± 36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_comprehension(words)
693 µs ± 42.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_generator(words)
750 µs ± 28.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_join_split(words)
796 µs ± 103 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
s and s.strip()
그냥 간단하게 할 수 있습니다 s.strip()
.
s and s.strip()
우리가 완전히 filter(None, words)
대답 하고 싶다면 대답 이 필요합니다 . 위의 x2 샘플 기능을 수정하고 x2 잘못된 기능을 삭제했습니다.
공백과 값이 조합 된 목록의 경우 간단한 목록 이해를 사용하십시오.
>>> s = ['I', 'am', 'a', '', 'great', ' ', '', ' ', 'person', '!!', 'Do', 'you', 'think', 'its', 'a', '', 'a', '', 'joke', '', ' ', '', '?', '', '', '', '?']
보시다시피이 목록에는 공백과 null 요소가 조합되어 있습니다. 스 니펫 사용하기-
>>> d = [x for x in s if x.strip()]
>>> d
>>> d = ['I', 'am', 'a', 'great', 'person', '!!', 'Do', 'you', 'think', 'its', 'a', 'a', 'joke', '?', '?']
for x in list
경우while loop
괜찮습니다. 루프는 빈 문자열이 더 이상 없을 때까지 빈 문자열을 제거한 다음 중지합니다. 나는 실제로 질문을 보지 않았지만 (제목 만) 가능성과 똑같은 루프로 대답했습니다! 메모리를 위해 이해력 또는 필터를 사용하지 않으려는 경우 매우 파이썬적인 솔루션입니다.