2013-11-03 3 views
1

어제 질문을했고 팀 피터스 덕분에 해결되었습니다. 질문은 여기에있다.itertools.product 반전 된 튜플 반복 제거

itertools.product eliminating repeated elements

새로운 질문이 더 버전입니다. 이번에는 튜플 내부에 튜플을 생성 해 보겠습니다. 다음은 그 예입니다. itertools.product이 내가 무엇을 얻을 기능에 내가 그것을 사용

lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]] 

, 나는 방법을 변경하려면

((1, 2), (5, 2), (2, 1)) 
((1, 2), (5, 2), (1, 2)) 
((1, 2), (1, 2), (2, 1)) 
((1, 2), (1, 2), (1, 2)) 
((3, 4), (5, 2), (2, 1)) 
((3, 4), (5, 2), (1, 2)) 
((3, 4), (1, 2), (2, 1)) 
((3, 4), (1, 2), (1, 2)) 

그 시퀀스는 그 안에 (A, B)이있는 경우 , (b, a)를 가질 수 없다. 이 예제에서이 시퀀스를 보면 ((3, 4), (1, 2), (2, 1)) 안에 (1,2)와 (2,1)이 있습니다. 따라서이 시퀀스 ((3, 4), (1, 2), (2, 1))은 결과로 고려되어서는 안됩니다.

내가 말했듯이 이전에 비슷한 질문을했는데,이 경우 중복 요소를 고려하지 않았습니다. 나는 내 문제에 적응하려고 노력한다. 수정 된 코드입니다. 이전 버전에서 변경된 부분은 주석에 사용됩니다.

def reverse_seq(seq): 
    s = [] 
    for i in range(len(seq)): 
     s.append(seq[-i-1])   
    return tuple(s) 


def uprod(*seqs): 
    def inner(i): 
     if i == n: 
      yield tuple(result) 
      return 
     for elt in sets[i] - reverse: 
      #seen.add(elt) 
      rvrs = reverse_seq(elt) 
      reverse.add(rvrs) 
      result[i] = elt 
      for t in inner(i+1): 
       yield t 
      #seen.remove(elt) 
      reverse.remove(rvrs) 

    sets = [set(seq) for seq in seqs] 
    n = len(sets) 
    #seen = set() 
    reverse = set() 
    result = [None] * n 
    for t in inner(0): 
     yield t 

내 의견으로는이 코드는 작동해야하지만 입력은 lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]]입니다. 내가 어디 잘못되었는지 이해할 수 없었다. 세트를 사용하여 내가 조금 다르게하고있어 출력이

for i in uprod(*lis): 
    print i 

,

((1, 2), (1, 2), (1, 2)) 
Traceback (most recent call last): 
    File "D:\Users\SUUSER\workspace tree\sequence_covering _array\denemeler_buraya.py", line 39, in <module> 
    for i in uprod(*lis): 
    File "D:\Users\SUUSER\workspace tree\sequence_covering _array\denemeler_buraya.py", line 32, in uprod 
    for t in inner(0): 
    File "D:\Users\SUUSER\workspace tree\sequence_covering _array\denemeler_buraya.py", line 22, in inner 
    for t in inner(i+1): 
    File "D:\Users\SUUSER\workspace tree\sequence_covering _array\denemeler_buraya.py", line 25, in inner 
    reverse.remove(rvrs) 
KeyError: (2, 1) 

감사합니다,

+0

실제 오류가 있습니까? 그렇다면 오류 메시지를 게시 할 수 있습니까? – rlms

+0

게시물에 오류 메시지를 추가했습니다. – genclik27

답변

1

문제 는 (중복)를 추가하기 전에 rvrsreverse 이미을 경우에도, 당신은 무조건 reverse.remove(rvrs)을 할 것입니다.

  remove_later = rvrs not in reverse 

전에 :

  reverse.add(rvrs) 

을하고 제거 코드를 변경 : 그래서 삽입

  if remove_later: 
       reverse.remove(rvrs) 

그런 다음 출력은 다음과 같습니다

((1, 2), (1, 2), (1, 2)) 
((1, 2), (5, 2), (1, 2)) 
((3, 4), (1, 2), (1, 2)) 
((3, 4), (5, 2), (1, 2)) 
((3, 4), (5, 2), (2, 1)) 

Unrelatedly, 당신은 던질 수 reverse_seq() 함수 대신 다음과 같이 작성하십시오.

  rvrs = elt[::-1] 
+0

답변을 다시 해주셔서 감사합니다. 그것은 작동합니다 :) – genclik27

1

는 순서가 필요하지 않습니다 순서를 제거합니다. 실제로 frozensets를 사용하므로 쉽게 중첩 할 수 있습니다.

우선 튜플 수의 순서를 무시해야하므로 lis을 (고정) 세트 목록으로 변환합니다.

>>> lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]] 
>>> lis_ = [[frozenset(x) for x in y] for y in lis] 

다음으로, 우리는 제품을 만든 다음 세트에 결과를 넣어, 그래서 우리는 중복 제거 :

>>> result = set(x for x in itertools.product(*lis_)) 
>>> result 
{(frozenset({3, 4}), frozenset({1, 2}), frozenset({1, 2})), (frozenset({1, 2}), frozenset({1, 2}), frozenset({1, 2})), (frozenset({3, 4}), frozenset({2, 5}), frozenset({1, 2})), (frozenset({1, 2}), frozenset({2, 5}), frozenset({1, 2}))} 

그리고 우리는 이미 이루어집니다.

>>> for r in result: 
     print([tuple(x) for x in r]) 

[(3, 4), (1, 2), (1, 2)] 
[(1, 2), (1, 2), (1, 2)] 
[(3, 4), (2, 5), (1, 2)] 
[(1, 2), (2, 5), (1, 2)] 

단지 itertools.product에서 결과를 필터링

다른 솔루션 :

지금 그를 인쇄 할 경우는 (출력의 frozenset() 부분을 제거하기 조금 더 예뻐, 당신은 당신의 결과를 가지고
>>> lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]] 
>>> seenProducts = set() 
>>> for p in itertools.product(*lis): 
     product = tuple(frozenset(x) for x in p) 
     if product not in seenProducts: 
      seenProducts.add(product) 
      print(p) # print original product 

((1, 2), (5, 2), (2, 1)) 
((1, 2), (1, 2), (2, 1)) 
((3, 4), (5, 2), (2, 1)) 
((3, 4), (1, 2), (2, 1)) 
+0

답변 주셔서 감사하지만 제 경우에는 순서가 중요합니다. 왜 튜플을 사용합니까? – genclik27

+1

순서가 중요하면 같은 항목이지만 순서가 다른 두 개의 튜플이 동일한 것으로 간주되는 것은 의미가 없습니다. – poke

+0

아니요, 이들은 동일한 것으로 간주되지 않습니다. 나는 그 (것)들이 동일한 순서에 있기 바라지 않는다. 나중에 다른 프로그램에서이 데이터를 입력으로 사용하겠습니다. 데이터에 (a, b)와 (b, a)가 동시에 있으면 false를 반환합니다. 그래서, 나는 이러한 결과를 제거해야합니다. – genclik27