문제

내가 목록으로 15 번호,그리고 나는 필요한 일부를 작성하는 코드를 생산하는 모든 32,768 조합을 사람들의 숫자입니다.

내가 찾았 일부 코드 (에 의해 인터넷 검색)는 분명히 무엇을 찾고 있어요,하지만 나는 코드는 상당히 불투명하고 이를 사용하여주의습니다.Plus 느낌을 가지고 있어야 합니다 더 많은 우아한 솔루션입니다.

는 나에게 발생 것을 그냥 루프를 통해 소수의 정수 1-32768 변환 사람들을 바이너리,사용에 대한 필터로 선택하는 적절한 숫자입니다.

사람이 알아의 더 좋은 방법은?용 map(), 어쩌면?

도움이 되었습니까?

해결책

살펴보십시오 itertools.combinations:

itertools.combinations(iterable, r)

입력 반복에서 요소의 Renger Length Seccetences를 반환합니다.

조합은 사전 정렬 순서로 방출됩니다. 따라서 입력 반복 가능이 정렬되면 조합 튜플이 정렬 된 순서로 생성됩니다.

2.6 이후 배터리가 포함되어 있습니다!

다른 팁

이 답변 중 하나를 놓치 측면:OP 묻는 모든 조합에 대한...지 조합의 길이"r".

그래서 당신은 하나가 루프를 통해 모든 길이"L":

import itertools

stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
    for subset in itertools.combinations(stuff, L):
        print(subset)

또는-만약 당신을 얻고 싶은 시선을 끄는(거나 구부의 뇌이 당신의 코드 후)-당신을 생성할 수 있는 체인의"조합()"발전기,그리고 반복하는:

from itertools import chain, combinations
def all_subsets(ss):
    return chain(*map(lambda x: combinations(ss, x), range(0, len(ss)+1)))

for subset in all_subsets(stuff):
    print(subset)

여기에 게으른 하이라이너,도를 사용하여 itertools:

from itertools import compress, product

def combinations(items):
    return ( set(compress(items,mask)) for mask in product(*[[0,1]]*len(items)) )
    # alternative:                      ...in product([0,1], repeat=len(items)) )

주요 이 대답:2^N--조합과 같은 수의 바이너리 문자열의 길이 N.에 대한 각 바이너리,문자열을 선택할 모든 요소에 해당하"1"입니다.

items=abc * mask=###
 |
 V
000 -> 
001 ->   c
010 ->  b
011 ->  bc
100 -> a
101 -> a c
110 -> ab
111 -> abc

음 사항을 고려해야 합니다.

  • 이 필요할 수 있는 통화 len(...)items (해결 방법:는 경우 items 같은 뭔가가 반복 가능한 다음과 같은 발전기 설정,그것으로 첫 번째 목록으로 items=list(_itemsArg))
  • 이 필요합하는 순서의 반복에 items 지 않은 랜덤(해결 방법:지 않 insane)
  • 이 필요로 하는 항목은 독특한,또는 다른 {2,2,1}{2,1,1} 모두 붕괴 {2,1} (해결 방법:사 collections.Counter 으로 대체하는 set;그것은 기본적으로 multiset...을 할 수 있습니다 하지만 나중에 사용 tuple(sorted(Counter(...).elements())) 해야 하는 경우 그것을 해쉬)

데모

>>> list(combinations(range(4)))
[set(), {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}, {0}, {0, 3}, {0, 2}, {0, 2, 3}, {0, 1}, {0, 1, 3}, {0, 1, 2}, {0, 1, 2, 3}]

>>> list(combinations('abcd'))
[set(), {'d'}, {'c'}, {'c', 'd'}, {'b'}, {'b', 'd'}, {'c', 'b'}, {'c', 'b', 'd'}, {'a'}, {'a', 'd'}, {'a', 'c'}, {'a', 'c', 'd'}, {'a', 'b'}, {'a', 'b', 'd'}, {'a', 'c', 'b'}, {'a', 'c', 'b', 'd'}]

에서 의견에회가 직접 참여 할 수있는 매우 응답 by@댄서 언급은 powerset() 레시피 itertools 문서—중 하나를 포함하여 Dan 자신. 그러나, 지금까지 없는 게시으로 대답합니다.이후 그것은 아마 중 하나 더 하지 않을 경우 가장 좋은 방법은 문제가 및어 작은 격려 에서 또 다른 주석,그것은 아래와 같습니다.기능 생산 모든 독특한 조합의 목록 요소의 길이 가능한(등을 포함하는 사람들로 그리고 모든 요소가).

참고:는 경우,미묘하게 다른 목표를 얻을만한 조합의 독특한 요소를 줄 변경 s = list(iterable) 하기 s = list(set(iterable)) 을 제거하는 모든 중복 요소입니다.에 관계없이,사실 iterable 궁극적으로 설정 list 을 의미합니 작업으로 발전기(발전과는 달리 여러 가지의 다른 답변).

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)  # allows duplicate elements
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

stuff = [1, 2, 3]
for i, combo in enumerate(powerset(stuff), 1):
    print('combo #{}: {}'.format(i, combo))

출력:

combo #1: ()
combo #2: (1,)
combo #3: (2,)
combo #4: (3,)
combo #5: (1, 2)
combo #6: (1, 3)
combo #7: (2, 3)
combo #8: (1, 2, 3)

재귀를 사용하는 것은 다음과 같습니다.

>>> import copy
>>> def combinations(target,data):
...     for i in range(len(data)):
...         new_target = copy.copy(target)
...         new_data = copy.copy(data)
...         new_target.append(data[i])
...         new_data = data[i+1:]
...         print new_target
...         combinations(new_target,
...                      new_data)
...                      
... 
>>> target = []
>>> data = ['a','b','c','d']
>>> 
>>> combinations(target,data)
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'd']
['a', 'c']
['a', 'c', 'd']
['a', 'd']
['b']
['b', 'c']
['b', 'c', 'd']
['b', 'd']
['c']
['c', 'd']
['d']

이 하나의 라이너는 모든 조합을 제공합니다 (사이 0 그리고 n 원본 목록/세트에 포함 된 경우 항목 n 고유 한 요소) 및 기본 방법을 사용합니다 itertools.combinations:

파이썬 2

from itertools import combinations

input = ['a', 'b', 'c', 'd']

output = sum([map(list, combinations(input, i)) for i in range(len(input) + 1)], [])

파이썬 3

from itertools import combinations

input = ['a', 'b', 'c', 'd']

output = sum([list(map(list, combinations(input, i))) for i in range(len(input) + 1)], [])

출력은 다음과 같습니다.

[[],
 ['a'],
 ['b'],
 ['c'],
 ['d'],
 ['a', 'b'],
 ['a', 'c'],
 ['a', 'd'],
 ['b', 'c'],
 ['b', 'd'],
 ['c', 'd'],
 ['a', 'b', 'c'],
 ['a', 'b', 'd'],
 ['a', 'c', 'd'],
 ['b', 'c', 'd'],
 ['a', 'b', 'c', 'd']]

온라인으로 시도하십시오 :

http://ideone.com/coghfx

나는 벤이 실제로 요청한 Dan H에 동의합니다. 모두 조합. itertools.combinations() 모든 조합을 제공하지는 않습니다.

또 다른 문제는 입력 반복 가능이 크면 목록의 모든 대신 생성기를 반환하는 것이 더 낫다는 것입니다.

iterable = range(10)
for s in xrange(len(iterable)+1):
  for comb in itertools.combinations(iterable, s):
    yield comb

이 간단한 코드를 사용하여 Python에서 목록의 모든 조합을 생성 할 수 있습니다.

import itertools

a = [1,2,3,4]
for i in xrange(0,len(a)+1):
   print list(itertools.combinations(a,i))

결과는 다음과 같습니다.

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

나는 Itertools 나 다른 추가 라이브러리를 가져 오지 않고 답을 찾는 사람들을 위해이 기능을 추가 할 것이라고 생각했습니다.

def powerSet(items):
    """
    Power set generator: get all possible combinations of a list’s elements

    Input:
        items is a list
    Output:
        returns 2**n combination lists one at a time using a generator 

    Reference: edx.org 6.00.2x Lecture 2 - Decision Trees and dynamic programming
    """

    N = len(items)
    # enumerate the 2**N possible combinations
    for i in range(2**N):
        combo = []
        for j in range(N):
            # test bit jth of integer i
            if (i >> j) % 2 == 1:
                combo.append(items[j])
        yield combo

간단한 수율 생성기 사용 :

for i in powerSet([1,2,3,4]):
    print (i, ", ",  end="")

위의 사용 예제에서 출력 :

[] , [1] , [2] , [1, 2] , [3] , [1, 3] , [2, 3] , [1, 2, 3] , [4] , [1, 4] , [2, 4] , [1, 2, 4] , [3, 4] , [1, 3, 4] , [2, 3, 4] , [1, 2, 3, 4] ,

다음은 사용을 포함하는 또 다른 솔루션 (한 라이너)입니다. itertools.combinations 기능이지만 여기서는 이중 목록 이해력을 사용합니다 (루프 또는 합계와 반대로) :

def combs(x):
    return [c for i in range(len(x)+1) for c in combinations(x,i)]

데모:

>>> combs([1,2,3,4])
[(), 
 (1,), (2,), (3,), (4,), 
 (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), 
 (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), 
 (1, 2, 3, 4)]

이것은 재귀를 지원하는 모든 프로그래밍 언어로 쉽게 전송할 수있는 접근법입니다. (ITERTOOL 없음, 수율 없음, 목록 이해력):

def combs(a):
    if len(a) == 0:
        return [[]]
    cs = []
    for c in combs(a[1:]):
        cs += [c, c+[a[0]]]
    return cs

>>> combs([1,2,3,4,5])
[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], ..., [5, 4, 3, 2, 1]]

IterTools를 사용하여 수행 할 수 있습니다

순열을 위해

이 방법은 목록을 입력으로 취하고 목록 양식에서 길이 L의 순열을 포함하는 튜플 목록을 반환합니다.

# A Python program to print all  
# permutations of given length 
from itertools import permutations 

# Get all permutations of length 2 
# and length 2 
perm = permutations([1, 2, 3], 2) 

# Print the obtained permutations 
for i in list(perm): 
    print (i) 

조합

이 메소드는 목록과 입력 r을 입력으로 가져 와서 목록 양식에서 길이 r의 가능한 모든 조합을 포함하는 튜플 목록을 반환합니다.

# A Python program to print all  
# combinations of given length 
from itertools import combinations 

# Get all combinations of [1, 2, 3] 
# and length 2 
comb = combinations([1, 2, 3], 2) 

# Print the obtained combinations 
for i in list(comb): 
    print (i) 

보다 이것

아래는"표준을 재귀"대답과 유사한 다른 비슷한 대답 https://stackoverflow.com/a/23743696/711085 .(리지 않는 현실적으로 걱정을 실행에 대해 문의하는 방법에 대한 자세한 내 공간이 있기 때문에 아무 방법으로 우리가 처리할 수 있는 모든 N!순열.)

그것은 방문하는 모든 요소에서 차례,그리고 중 하나 그것은 또는 나뭇잎(우리는 할 수 있습을 직접 참조 2^N 티에서 이 알고리즘).

def combs(xs, i=0):
    if i==len(xs):
        yield ()
        return
    for c in combs(xs,i+1):
        yield c
        yield c+(xs[i],)

Demo:

>>> list( combs(range(5)) )
[(), (0,), (1,), (1, 0), (2,), (2, 0), (2, 1), (2, 1, 0), (3,), (3, 0), (3, 1), (3, 1, 0), (3, 2), (3, 2, 0), (3, 2, 1), (3, 2, 1, 0), (4,), (4, 0), (4, 1), (4, 1, 0), (4, 2), (4, 2, 0), (4, 2, 1), (4, 2, 1, 0), (4, 3), (4, 3, 0), (4, 3, 1), (4, 3, 1, 0), (4, 3, 2), (4, 3, 2, 0), (4, 3, 2, 1), (4, 3, 2, 1, 0)]

>>> list(sorted( combs(range(5)), key=len))
[(), 
 (0,), (1,), (2,), (3,), (4,), 
 (1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (4, 3), 
 (2, 1, 0), (3, 1, 0), (3, 2, 0), (3, 2, 1), (4, 1, 0), (4, 2, 0), (4, 2, 1), (4, 3, 0), (4, 3, 1), (4, 3, 2), 
 (3, 2, 1, 0), (4, 2, 1, 0), (4, 3, 1, 0), (4, 3, 2, 0), (4, 3, 2, 1), 
 (4, 3, 2, 1, 0)]

>>> len(set(combs(range(5))))
32

이 코드는 중첩 된 목록이있는 간단한 알고리즘을 사용합니다 ...

# FUNCTION getCombos: To generate all combos of an input list, consider the following sets of nested lists...
#
#           [ [ [] ] ]
#           [ [ [] ], [ [A] ] ]
#           [ [ [] ], [ [A],[B] ],         [ [A,B] ] ]
#           [ [ [] ], [ [A],[B],[C] ],     [ [A,B],[A,C],[B,C] ],                   [ [A,B,C] ] ]
#           [ [ [] ], [ [A],[B],[C],[D] ], [ [A,B],[A,C],[B,C],[A,D],[B,D],[C,D] ], [ [A,B,C],[A,B,D],[A,C,D],[B,C,D] ], [ [A,B,C,D] ] ]
#
#  There is a set of lists for each number of items that will occur in a combo (including an empty set).
#  For each additional item, begin at the back of the list by adding an empty list, then taking the set of
#  lists in the previous column (e.g., in the last list, for sets of 3 items you take the existing set of
#  3-item lists and append to it additional lists created by appending the item (4) to the lists in the
#  next smallest item count set. In this case, for the three sets of 2-items in the previous list. Repeat
#  for each set of lists back to the initial list containing just the empty list.
#

def getCombos(listIn = ['A','B','C','D','E','F'] ):
    listCombos = [ [ [] ] ]     # list of lists of combos, seeded with a list containing only the empty list
    listSimple = []             # list to contain the final returned list of items (e.g., characters)

    for item in listIn:
        listCombos.append([])   # append an emtpy list to the end for each new item added
        for index in xrange(len(listCombos)-1, 0, -1):  # set the index range to work through the list
            for listPrev in listCombos[index-1]:        # retrieve the lists from the previous column
                listCur = listPrev[:]                   # create a new temporary list object to update
                listCur.append(item)                    # add the item to the previous list to make it current
                listCombos[index].append(listCur)       # list length and append it to the current list

                itemCombo = ''                          # Create a str to concatenate list items into a str
                for item in listCur:                    # concatenate the members of the lists to create
                    itemCombo += item                   # create a string of items
                listSimple.append(itemCombo)            # add to the final output list

    return [listSimple, listCombos]
# END getCombos()

Itertools를 사용하여 모두 조합, 그러나 당신 ~할 수 있다 당신이 욕망을하는 경우, 당신이 코드를 만들고 싶은 경우에만 목록 이해만으로 부분적으로 달성하십시오. 많이

두 쌍의 조합 :

    lambda l: [(a, b) for i, a in enumerate(l) for b in l[i+1:]]


그리고 3 쌍의 조합의 경우 다음과 같이 쉽습니다.

    lambda l: [(a, b, c) for i, a in enumerate(l) for ii, b in enumerate(l[i+1:]) for c in l[i+ii+2:]]


결과는 itertools.combinations를 사용하는 것과 동일합니다.

import itertools
combs_3 = lambda l: [
    (a, b, c) for i, a in enumerate(l) 
    for ii, b in enumerate(l[i+1:]) 
    for c in l[i+ii+2:]
]
data = ((1, 2), 5, "a", None)
print("A:", list(itertools.combinations(data, 3)))
print("B:", combs_3(data))
# A: [((1, 2), 5, 'a'), ((1, 2), 5, None), ((1, 2), 'a', None), (5, 'a', None)]
# B: [((1, 2), 5, 'a'), ((1, 2), 5, None), ((1, 2), 'a', None), (5, 'a', None)]

IterTools를 사용하지 않고 :

def combine(inp):
    return combine_helper(inp, [], [])


def combine_helper(inp, temp, ans):
    for i in range(len(inp)):
        current = inp[i]
        remaining = inp[i + 1:]
        temp.append(current)
        ans.append(tuple(temp))
        combine_helper(remaining, temp, ans)
        temp.pop()
    return ans


print(combine(['a', 'b', 'c', 'd']))

여기에는 두 가지 구현 itertools.combinations

하나의 목록을 반환하는

def combinations(lst, depth, start=0, items=[]):
    if depth <= 0:
        return [items]
    out = []
    for i in range(start, len(lst)):
        out += combinations(lst, depth - 1, i + 1, items + [lst[i]])
    return out

하나의 반환하는 발전기

def combinations(lst, depth, start=0, prepend=[]):
    if depth <= 0:
        yield prepend
    else:
        for i in range(start, len(lst)):
            for c in combinations(lst, depth - 1, i + 1, prepend + [lst[i]]):
                yield c

참고로 제공하는 도우미 기능을 사는 것이 좋기 때문에 추가 인자는 정적이고 변경되지 않는 모든 통화

print([c for c in combinations([1, 2, 3, 4], 3)])
# [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

# get a hold of prepend
prepend = [c for c in combinations([], -1)][0]
prepend.append(None)

print([c for c in combinations([1, 2, 3, 4], 3)])
# [[None, 1, 2, 3], [None, 1, 2, 4], [None, 1, 3, 4], [None, 2, 3, 4]]

이것은 매우 피상적인 경우 하지만 더 나은 미안한 것보다 안전

이건 어때 .. 목록 대신 문자열을 사용했지만 같은 것 .. 문자열은 파이썬에서 목록처럼 취급 될 수 있습니다.

def comb(s, res):
    if not s: return
    res.add(s)
    for i in range(0, len(s)):
        t = s[0:i] + s[i + 1:]
        comb(t, res)

res = set()
comb('game', res) 

print(res)

itertools의 조합

import itertools
col_names = ["aa","bb", "cc", "dd"]
all_combinations = itertools.chain(*[itertools.combinations(col_names,i+1) for i,_ in enumerate(col_names)])
print(list(all_combinations))

감사

없이 itertools Python 3에서는 다음과 같은 일을 할 수 있습니다.

def combinations(arr, carry):
    for i in range(len(arr)):
        yield carry + arr[i]
        yield from combinations(arr[i + 1:], carry + arr[i])

처음 어디서 carry = "".

목록 이해력 사용 :

def selfCombine( list2Combine, length ):
    listCombined = str( ['list2Combine[i' + str( i ) + ']' for i in range( length )] ).replace( "'", '' ) \
                     + 'for i0 in range(len( list2Combine ) )'
    if length > 1:
        listCombined += str( [' for i' + str( i ) + ' in range( i' + str( i - 1 ) + ', len( list2Combine ) )' for i in range( 1, length )] )\
            .replace( "', '", ' ' )\
            .replace( "['", '' )\
            .replace( "']", '' )

    listCombined = '[' + listCombined + ']'
    listCombined = eval( listCombined )

    return listCombined

list2Combine = ['A', 'B', 'C']
listCombined = selfCombine( list2Combine, 2 )

출력은 다음과 같습니다.

['A', 'A']
['A', 'B']
['A', 'C']
['B', 'B']
['B', 'C']
['C', 'C']

이것이 나의 구현입니다

    def get_combinations(list_of_things):
    """gets every combination of things in a list returned as a list of lists

    Should be read : add all combinations of a certain size to the end of a list for every possible size in the
    the list_of_things.

    """
    list_of_combinations = [list(combinations_of_a_certain_size)
                            for possible_size_of_combinations in range(1,  len(list_of_things))
                            for combinations_of_a_certain_size in itertools.combinations(list_of_things,
                                                                                         possible_size_of_combinations)]
    return list_of_combinations
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
    return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
    for i in reversed(range(r)):
        if indices[i] != i + n - r:
            break
    else:
        return
    indices[i] += 1
    for j in range(i+1, r):
        indices[j] = indices[j-1] + 1
    yield tuple(pool[i] for i in indices)


x = [2, 3, 4, 5, 1, 6, 4, 7, 8, 3, 9]
for i in combinations(x, 2):
    print i

누군가가 반전 된 목록을 찾고 있다면 :

stuff = [1, 2, 3, 4]

def reverse(bla, y):
    for subset in itertools.combinations(bla, len(bla)-y):
        print list(subset)
    if y != len(bla):
        y += 1
        reverse(bla, y)

reverse(stuff, 1)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top