2017-12-14 18 views
2

문자열 목록의 모든 가능한 조합에 중복을 피하고자합니다 (예 : 1122은 내 문맥에 2211과 동일하므로 하나 또는 다른 문자 만 사용해야 함). 결과 목록).중복을 피하고 문자열 조합에 필터를 적용하는 방법

또한 조합 중에 필터를 적용하고 싶습니다. 예를 들어 결과에 3이 포함 된 문자열을 포함하고 싶지 않습니다.

이 논리는 어떻게 처리해야합니까?

import itertools 

def main(): 

    newkeywords = [] 
    keywords = ["".join(i) for i in itertools.product(["11", "22", "33"], repeat = 2)] 
    for item in keywords: 
     newitem = "".join(sorted(item)) 
     if "3" not in newitem and newitem not in newkeywords: 
      newkeywords.append(newitem) 
    print(newkeywords) 

main() 

결과 :

이 코드는이 당신이 원하는 것을해야

>>> keywords = [''.join(i) for i in itertools.product(['11', '22', '33'], repeat = 2)] 
>>> keywords 
['1111', '1122', '1133', '2211', '2222', '2233', '3311', '3322', '3333'] 
+0

'2222'및 '3333'도 건너 뛸 수 있습니까? – RomanPerekhrest

+0

정렬 된 문자열이 새 목록에없는 경우 원래 문자열을 추가하고 각 문자열을 반복하고 정렬 할 수 있습니다. https://stackoverflow.com/questions/15046242/how-to-sort-the-letters-in-a-string- alphabetically-in-python 당신이 가고 싶은 올바른 방향 인 것처럼 보이는다면 나는 더 나은 대답을 쓸 수 있습니다. – sniperd

+0

3을 포함하는 모든 문자열을 삭제해야합니다. – Michael

답변

2

실제 데이터에 따라 수 있습니다 덜 효율적인 방법이 있지만 아래의 알고리즘이 작동합니다. 우리는 간단한 비교를 통해 중복을 제거합니다. 나는 '3'을 함수에 넣었습니다. 그것은리스트 독해에서 직접하는 것보다 약간 느리지 만, 코드를 좀 더 일반적으로 만든다.

import itertools 

bases = ['11', '22', '33', '44'] 

def is_ok(u, v): 
    ''' Test if a u,v pair is permitted ''' 
    return not ('3' in u or '3' in v) 

keywords = [u+v for u, v in itertools.product(bases, repeat = 2) if u <= v and is_ok(u, v)] 

출력

['1111', '1122', '1144', '2222', '2244', '4444'] 
print(keywords) 
0

조합하고있다

['1111', '1122', '2222'] 

그것은 새 목록을 만드는, 그리고 그 분류하는 경우 항목 (1122가 2211과 같음)이 있거나 숫자 "3"이 있으면 새 목록에 추가하지 마십시오.

2

동일 itertools.combinations_with_replacement를 필터링 할 수있다 :

코드

import itertools as it 


bases = ["11", "22", "33", "44"] 

[x+y for x,y in it.combinations_with_replacement(bases, 2) if "3" not in x+y] 
# ['1111', '1122', '1144', '2222', '2244', '4444'] 

버전보다 일반적이다하지 않으며 숫자 문자열 비교에 의존합니다.


세부the docs에서

이 작품 왜 우리가 이해할 수 :

요소가없는 곳 combinations_with_replacement()의 코드도 항목을 필터링 한 후 product()의 서브 순서로 표현 될 수있다 정렬 된 순서로 (입력 풀의 위치에 따라)

def combinations_with_replacement(iterable, r): 
    pool = tuple(iterable) 
    n = len(pool) 
    for indices in product(range(n), repeat=r): 
     if sorted(indices) == list(indices): 
      yield tuple(pool[i] for i in indices) 

이러한 방식으로 각 항목은 고유 색인과 연관됩니다. 두 항목의 색인을 비교할 때 정렬 된 조합 만 항목을 산출하는 데 사용됩니다. 나머지 색인은 이미 본 것처럼 삭제됩니다.

(0, 0) 
(0, 1) 
(0, 2) 
(0, 3) 
(1, 0)           # discarded 
(1, 1) 
... 

이 도구와 itertools.product 사이의 유사성에 대한 자세한 내용은 the docs를 참조하십시오.