2014-12-26 1 views
11

문자열의 처음 세 문자를 기반으로 유사한 항목을 목록에 그룹화하려고합니다. 예를 들어 :비슷한 항목을 목록에 그룹화하는 방법?

test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 

어떻게이 그룹 그룹으로 위의 목록 항목은 문자 (예를 들어, 'abc')의 첫 번째 그룹을 기반으로 할 수 있습니까? 다음은 의도 출력 :

output = {1: ('abc_1_2', 'abc_2_2'), 2: ('hij_1_1',), 3: ('xyz_1_2', 'xyz_2_2')} 

또는 I 성공없이이를 위해 itertools.groupby를 사용하여 시도

output = [['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']] 

:

>>> import os, itertools 
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 
>>> [list(g) for k.split("_")[0], g in itertools.groupby(test)] 
[['abc_1_2'], ['abc_2_2'], ['hij_1_1'], ['xyz_1_2'], ['xyz_2_2']] 

I을 살펴 보았다 성공하지 못한 다음 게시물 :

How to merge similar items in a list. 예에서는 지나치게 복잡해 보이는 접근 방식을 사용하여 유사한 항목 (예 : 'house''Hose')을 그룹화합니다.

How can I group equivalent items together in a Python list?. 이것이 내가 명단 이해를위한 아이디어를 발견 한 곳입니다.

답변

8

.split("_")[0] 부분은 두 번째 인수로 itertools.groupby에 전달하는 단일 인수 함수 내에 있어야합니다. 결과는 즉시 폐기되기 때문에

>>> import os, itertools 
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 
>>> [list(g) for _, g in itertools.groupby(test, lambda x: x.split('_')[0])] 
[['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']] 
>>> 

for ... 부분에있는 것은 아무것도하지 않는다. 당신은 단지 하나의 분할을 할 때 또한


, str.partition를 사용하는 것이 좀 더 효율적으로 될 것입니다 :

[list(g) for _, g in itertools.groupby(test, lambda x: x.partition('_')[0])] 

데모 :

>>> from timeit import timeit 
>>> timeit("'hij_1_1'.split('_')") 
1.3149855638076913 
>>> timeit("'hij_1_1'.partition('_')") 
0.7576401470019234 
>>> 

이 주요 관심사로가 아닌 두 가지 방법 모두 작은 문자열에 대해서는 꽤 빠르지 만 언급 할 것입니다.

+0

감사합니다. 위대한 작품입니다. 최근 입력 목록이 정렬되었는지 확인하는 것이 좋습니다. 'test = sorted ([ 'abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'])'. 그렇지 않으면 입력리스트가 정렬되지 않으면'itertools.groupby'가 예상대로 작동하지 않습니다. – Borealis

+1

예, 'itertools.groupby'를 사용하면 목록을 먼저 정렬하는 것이 좋습니다. 왜냐하면'groupby'는 비슷한 값의 실행 만 캡처하기 때문입니다. 목록이 정렬되지 않으면 일부를 놓칠 수 있습니다. 주된 관심사는'groupby'를 사용하는 방법에 관한 것이었고 여러분의 목록은 이미 정렬 되었기 때문에 나는 내 게시물에서 이것을 언급하는 것을 귀찮게하지 않았습니다. – iCodez