2012-09-27 3 views
2

나는 zip과 같은 함수를 작성하려고합니다. 나는 내가 의미하는 바를 설명하는 것에 능숙하지 않다. 그래서 나는 내가하려고하는 것에 대한 '코드'만을 보여줄 것이다.Python deep zip

a = [1,2,3,[4,5]] 
b = a[:] 
zip(a, b) == [(1,1), (2,2), (3,3), ([4,5],[4,5])] 
myzip(a, b) == [(1,1), (2,2), (3,3), [(4,4), (5,5)]] 

나는 너무 익숙하지 않아 재미 없다. 재귀 람다 (recursive lambdas)를 사용하여 간단하게 기능적인 방식으로 작성하여 코드를 더 예쁘게 만들려고합니다. 난 내가 지퍼 이와 비슷한 뭔가를 시도하고있다

def tree_map(func, tree): 
    return map(lambda x: func(x) if not isinstance(x, list) else tree_map(func, x), 
       tree) 

나무에 함수를 매핑 내가 쓴 다른 기능과 출력을 사용하기를 원하기 때문에이 같은 myzip 싶지만 보일 수 없다 그 주위에 내 머리를 감쌌다. 누구든지 myzip을 작성할 수있는 방법에 대한 아이디어가 있습니까?

편집 : tree_map을보세요! 그다지 예쁜 것은 아니다! 나는 적어도 그렇게 생각하지만, 나의 모국어는 Scheme : P 이며, 또한 myzip이 필요로하는만큼 깊게 가고 싶습니다. 기본적으로, 나는 myzip이 나무의 구조를 유지하기를 원합니다. 또한 myzip은 같은 모양의 나무 만 처리합니다.

+0

"코드를 더 예쁘게 만들기 위해 재귀 람다 (recursive lambdas)를 사용하여 간단한 기능 방식으로 작성하려고합니다." 그건 .. 음, 아니, 나는 코미디언 직유를 생각해 내지 않을거야. 그러나 람다 (lambdas)를 이용한 재귀 (recursion)는 여러분의 코드를 더 예쁘게 만들지 않을 것입니다. – DSM

+0

은 2 단계 수준에 불과하거나 무한대 여야합니까? – jterrace

+1

['itertools'] (http://docs.python.org/library/itertools.html#itertools.izip) 확인에 대해 생각해 보셨습니까? 여러분에게 영감을 줄 수있는 논리를 제시하는 파이썬 의사 코드가 있습니다 ... –

답변

7

나는 다음과 같은 일을해야 생각 :

import collections 

def myzip(*args): 
    if all(isinstance(arg, collections.Iterable) for arg in args): 
     return [myzip(*vals) for vals in zip(*args)] 
    return args 

결과 : 나는 유형 검사에 collections.Iterable 대신 list를 사용

>>> a = [1,2,3,[4,[5,6]]] 
>>> b = [1,2,3,[4,[5,6]]] 
>>> myzip(a, b) 
[(1, 1), (2, 2), (3, 3), [(4, 4), [(5, 5), (6, 6)]]] 

주 그렇게 행동이라고 튜플 더 같은 zip() 및 다른 iterables.

+0

AMAZING !!!!!! 이것은 완벽 해!!! 생각할 시간이 아니라면 시간이 걸렸을 거라고 생각합니다. 감사! – Broseph

+0

간단히 아름답습니다. –

+0

+1. 당신은 args의 _all_이리스트가 아니라 첫 번째 것이 아니라고 주장하고 싶을 것입니다. 그래서 예외가 아니라 합리적으로 (평평한 zip처럼) 할 수 있습니다. 물론 유효하지 않아야합니다. 예외는 완벽합니다. 또한, list 대신에'collections.Iterable'을 사용하기를 원할 수도 있습니다 (그래서 튜플 등을 깊이 압축 할 수 있습니다). 또는 전체를 목록 대신 반복 가능한 것으로 써도됩니다. 그러나 이것은 효과적이며, 멋지고 간단합니다. – abarnert

관련 문제