4

1 つのリストの値が繰り返され、もう 1 つのリストでは繰り返されない 2 つのリストのすべての組み合わせを見つける最良の方法は何ですか? 現在、繰り返しリストのすべての組み合わせを次のように取得できます。

import itertools
rep = ['A','B','C', 'D']
norep = ['1','2','3','4']
for i in itertools.combinations_with_replacement(rep,4):
    print i

非繰り返しリストのすべての組み合わせを取得できます。

for i in itertool.combinations(norep,4):
    print i

2 つのリストの組み合わせを、どちらも繰り返さないかのように取得できます。

for i in itertools.product([0, 1], repeat=4):
    print [(norep[j] if i else rep[j]) for j, i in enumerate(i)]

ただし、繰り返しリストと非繰り返しリストの組み合わせを取得する方法がわかりません。['A','1',Null] などの null 値を含む組み合わせも追加したいと思います。

4

2 に答える 2

2

これは私が得たものです。あなたにかなり近い:

from itertools import chain
from itertools import combinations
# Huge name!
from itertools import combinations_with_replacement as cwr
from itertools import starmap
from itertools import product

from operator import add

def _weird_combinations(rep, no_rep, n_from_rep, n_from_norep):
    return starmap(add, product(cwr(rep, n_from_rep),
                                combinations(no_rep, n_from_norep)))

def weird_combinations(rep, no_rep, n):
    rep, no_rep = list(rep), list(no_rep)

    # Allow Nones in the output to represent drawing less than n elements.
    # If either input has None in it, this will be confusing.
    rep.append(None)

    # We can't draw more elements from no_rep than it has.
    # However, we can draw as many from rep as we want.
    least_from_rep = max(0, n-len(no_rep))
    return chain.from_iterable(
            _weird_combinations(rep, no_rep, n_from_rep, n-n_from_rep)
            for n_from_rep in xrange(least_from_rep, n+1))
于 2013-07-21T23:26:58.610 に答える
0

私は解決策を思いついたと思いますが、これが間違っている場合は修正してください。また、よりエレガントなソリューションがあるかどうかも知りたいです。

まず、組み合わせの総数を考え出しました。置換なしのすべての組み合わせは、n!/r!(nr)! に等しくなります。置換すると、(m+s-1)!/s!(m-1)! に等しくなります。ここで、m と n は選択するアイテムの数、r と s は実際に選択するアイテムの数です。各組み合わせで必要なアイテムの合計 (キャップと呼びましょう) がわかっているので、置換なしタイプ (n=0) の 0 と置換タイプの「キャップ」 (m=3) の組み合わせの数を見つけます。そしてそれらの数を掛け合わせます。次に、置換なしタイプ (n=1) の 1 の組み合わせの数に、置換タイプ (m=2) の組み合わせ「cap-1」を掛けた数を加算します。これを、置換なしタイプ (n=3) に置換タイプ (m=0) の 0 を掛けた「キャップ」の組み合わせを最終的に追加するまで行います (@André Nicolas に感謝します)。

import itertools
from math import factorial as fact
norep = ['A','B','C']
rep = ['1','2','3']

cap = 3     #length of combinations, e.g. cap=3, combo1=123,combo2=A12,etc
combos = 0

for i in range(cap+1):
    combnorep = fact(len(norep))/(fact(cap-i)*fact(len(norep)-(cap-i)))
    combrep = fact(len(rep)+i-1)/(fact(i)*fact(len(rep)-1))
    combos = combos + combnorep*combrep
print combos

この例では、コンボ数は 38 です。次に、すべての組み合わせを出力したいと考えました。これを行うために、すべての置換、すべての置換なし、および 2 つの任意の組み合わせ (n=0、m=3;n=1、m=2; など) の組み合わせを決定しました。これは私が思いついたものです:

for i in range(cap+1):
    norepcomb = [j for j in itertools.combinations(norep,i)]
    repcomb = [k for k in itertools.combinations_with_replacement(rep,cap-i)]
    for l in itertools.product(norepcomb,repcomb):
        print list(itertools.chain.from_iterable(l))

を含めるには、置換の組み合わせをリストにnone含めるだけです。none特により良い解決策がある場合、またはこれが私が思うように機能しない場合は、これに関するフィードバックをお願いします. ありがとう!

于 2013-07-21T23:16:58.910 に答える