2014-04-05 2 views
2

튜플 대신 목록을 반환하려면 itertools.product이 필요합니다. 나는 현재 다음과 같은 자신 만의 함수를 작성하여이를 수행하고있다.itertools.product - 튜플 대신 목록 반환

def product_list(*args, **kwds): 
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy 
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 
    pools = map(tuple, args) * kwds.get('repeat', 1) 
    result = [[]] 
    for pool in pools: 
     result = [x + [y] for x in result for y in pool] 
    for prod in result: 
     yield list(prod) # Yields list() instead of tuple() 

코드는 Python 문서에서 왔으며, 마지막 행을 수정했다. 이것은 잘 작동하지만 매우 똑똑한 것 같지 않습니다.

다른 방법은 무엇입니까? 내가 decorator 같은 것을 사용하거나 자체 생성기 함수로 감싸는 것을 생각하고 있습니다. 나는 두 개념에 너무 익숙하지 않아 누군가가 나를 보여줄 수 있다면 감사 할 것입니다.

편집 내가 이런 지저분한 일하고 있어요 :

for r0 in product_list([0, 1], repeat=3): 
    r0.insert(0, 0) 
    for r1 in product_list([0, 1], repeat=3): 
     r1.insert(1, 0) 
     for r2 in product_list([0, 1], repeat=3): 
      r2.insert(2, 0) 
      for r3 in product_list([0, 1], repeat=3): 
       r3.insert(3, 0) 

그래서 난 내 함수가 매번 캐스팅하는 대신 목록을 반환 선호합니다. (나는 코드가 지저분하고 재귀가 필요하다는 것을 알고 있지만 나중에 생각할 것입니다. 위에서 설명한 내용을 수행하는 방법에 대해 더 자세히 알고 싶습니다.)

답변

4

itertools.product은 생성기이므로 쉽게 체인을 연결할 수 있습니다.

귀하의 예제 코드에서
(list(tup) for tup in itertools.product(iterable1, iterable2, etc)) 

, 당신은 발전기 표현을 사용할 수 있습니다, 또는 당신이 전면에 여분의 가치를 추가하는 다른 방법을 사용할 수 있습니다 여기리스트로 product에 의해 산출 각 튜플을 변경하는 발전기 표현이다 당신의 가치의 튜플로 유지하면서 :

for r0 in itertools.product([0, 1], repeat=3): 
    r0 = (0,) + r0 # keep r0 a tuple! 
    for r1 in itertools.product([0, 1], repeat=3): 
     r1 = (1,) + r1 # same here 
     # ... 

당신은 당신이 당신의 rN 변수를 사용하는지 보여주지 않기 때문에, 그것은 당신에게 갈 수있는 가장 좋은 방법 일 것입니다 무슨에 관해서는 명확한 대답을하는 것은 불가능합니다 . 실제로 코드 루프는 0 또는 1 개의 숫자를 계산하기 때문에 product 번의 호출을 통해 n이라는 목록을 생성 할 수 있습니다. 다른 r 값을

for bits in itertools.product([0, 1], repeat=3*n): 
    rs = [(i,) + bits[3*i:3*i+3] for i in range(n)] 
    # do something with the list of r tuples here 
+0

답장을 보내 주셔서 감사합니다. 내 편집을 참조하십시오. – mchangun