해당 요소가 두 공백 사이에있는 경우 목록 요소 결합


24

다음과 같은 입력이 있습니다.

['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

다음 ''과 같은 출력을 갖도록 요소를 결합하고 싶습니다 .

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

다음 join과 같이 슬라이싱을 사용 하고 나열했습니다.

a=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a[2:5] = [''.join(a[ 2: 5])]
a=['assembly', '', 'python', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

이것은 어느 정도 작동하지만 전체 목록에 대해이 명령을 반복하는 방법을 모르겠습니다.

답변:


27

사용 itertools.groupby:

from itertools import groupby

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = bool) if k]

산출:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

2
설명 : "bool"을 사용하여 빈 문자열 또는 없음과 같은 "Falsey"값을 확인합니다.
noɥʇʎԀʎzɐɹƆ

7

이것은 끔찍하고 해 키지 만

lambda b:lambda l:''.join(i or b for i in l).split(b)

목록의 연결에 포함되어 있지 않다고 보장 할 수있는 문자열을 취하고 원하는 것을 수행하는 함수를 반환합니다. 물론 특정 상황에서 한두 번만 사용하고 싶을 수 있으므로 목록의 요소에 공백이없는 것을 보장 할 수 있으면 다음과 같이 보일 수 있습니다.

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a = ''.join(i or ' ' for i in a).split(' ')

4

itertools를 사용할 수 없거나 사용하지 않으려는 경우 :

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
l_new = []
combined = ""
for idx, s in enumerate(l):
    if s != "":
        combined += s
        if idx == len(l)-1:
            l_new.append(combined)

    else:
        l_new.append(combined)
        combined = ""

3

당신은 이것을 할 수 있습니다 :

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = ['' == k for k in a]
indx = [i for i, x in enumerate(indx) if x] # get the indices.
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1] + a[indx[-1]+1:] # merge the list

산출:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

주석 후 편집 :

a = ['assembly', '','',  'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = [i for i, x in enumerate(a) if x == ''] # get the indices where '' occurs in the original list. 
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1 and indx[i+1] -indx[i] > 1] + a[indx[-1]+1:]
a_merged

산출:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

# get the indices.매우 유용한 의견이 아닙니다. 유용하게 만들 filter the indices to keep only those that correspond to whitespace거나 (예 :) 완전히 제거하는 것이 좋습니다 .
알렉산더-복원 모니카

또한 2 단계 프로세스를 간단히 단순화 할 수 없었 indices = [i for s in a if s == '']습니까?
알렉산더-복원 모니카

@Alexander 2 줄에 대한 제안이 구문 오류 일 것이라고 생각합니다. 라인 3과 같이 "is null string is equal"체크 만 추가하면 라인 2를 제거 할 수 있습니다.indx = [i for i, x in enumerate(a) if x == '']
Reimus Klinsman

불행히도,이 답변은 결합해야 할 첫 번째 또는 마지막 요소를 설명하지 않습니다. 같은 a = ['asse','mbly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c+', '+']그러나 당신이의 끝에서 널 (null) 문자열 목록을 추가하여 3 호선을 향상시킬 수처럼 보이는 enumerate([''] + a + [''])다음을 제거 a[0:indx[0]]하고 a[indx[-1]+1:]바로 옆에 서로 두 널 (null) 문자열이있는 경우 귀하의 라인 4.이 아직 고려하지 않습니다 그래도
Reimus Klinsman

1
좋은 의견에 대해 @KeiNagase에게 감사드립니다. 편집 내용을 참조하십시오.
순진

2

입력 분리 문자가 실제로 빈 문자열이면 다음을 수행 할 수 있습니다.

strlist = [x or ' ' for x in a]
joined = ''.join(strlist).split()
joined
['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

죄송합니다, 관련없는 문자열의 답변을 보지 못했습니다. 매개 변수없이 split ()하면 모든 공백이 축소되어 좀 더 강력합니다.
realgeek

1

꽤 오래되었지만 여전히 유용합니다.

from itertools import groupby

lst = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

new_lst = [''.join(values)
           for key, values in groupby(lst, key = lambda x: x == '')
           if not key]
print(new_lst)

이 결과

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

1

루프
내부 의 목록에 대해 루프를 실행 하여 요소를 임시 빈 문자열에 추가하고 요소가 빈 문자열인지 또는 목록의 마지막 요소인지 여부를 확인하십시오. true 인 경우 임시 변수를 출력 목록에 추가하고 값을 변경하십시오. 빈 문자열에 해당 변수의
코드 :

x=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
temp=''
output=[]
for y in x:
    temp=temp+y
    if y=='' or y==x[-1]:
        output.append(temp)
        temp=''

print(output)

산출: ['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']


1

Cris 답변이 대부분의 python 접근법을 사용 한다는 데 동의 하지만 Cris 답변을 약간 수정하는 것이 좋습니다 . 불필요한 모호성을 없애고 사용 groupby(l,key = bool)하는 대신groupby(l, key = lambda x: x !='')

from itertools import groupby

separator = ''
l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = lambda x: x !=separator) if k]

파이썬의 선 에서 언급했듯이 : 명시 적은 암시 적보다 낫습니다.

추신 : 나는 Cris 답변 에 대한 의견을 쓸만한 평판이 없기 때문에 새로운 답변 만 쓰고 있습니다.


1

기본 루프 / 테스트 만있는 다른 작업 버전 :

txt = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

out = []
temp = ''

for s in txt:
   if s == '':
      if temp != '':
         out.append(temp) 
         temp = ''
      out.append('')
   else:
      temp = temp + s

if temp != '':
   out.append(temp)

out
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.