0

n 個の入力リストに基づいてすべての可能な組み合わせを取得し、それらに何らかの処理を行う必要があります。

現在のコード例:

import itertools

# example inputs
list_small = [1, 2, 3]
list_medium = [444, 666, 242]
list_huge = [1680, 7559, 5573, 43658, 530, 11772, 284, 50078, 783, 37809, 6740, 37765, 74492, 50078, 783, 37809, 6740, 37765, 74492]

# out of the input list, I need to generate all numbers from 0 to the current list element
# e.g. if I have 6, I need to get [0, 1, 2, 3, 4, 5, 6]
# if I get a list [1, 2, 3], the output will be [[0, 1], [0, 1, 2], [0, 1, 2, 3]]
# I achieved this by doing it with xrange: [x for x in xrange(0, current_list_element + 1)]
# after that, I need to generate all possible combinations using the generated lists
# I managed to do this by using itertools.product()

# print this to get all possible combinations
# print list(itertools.product(*[[x for x in xrange(0, current_list_element + 1)] for current_list_element in list_medium]))

cumulative_sum = 0
for current_combination in itertools.product(*[[x for x in xrange(0, current_list_element + 1)] for current_list_element in list_medium]):
    # now I need to do some calculations to the current combination
    # e.g. get sum of all combinations, this is just an example
    cumulative_sum += sum(current_combination)

    # another example
    # get XOR sum of current combination, more at https://en.wikipedia.org/wiki/Exclusive_or
    print reduce(operator.xor, current_combination, 0)

# runs fast for list_small, then takes some time for list_medium and then takes ages for list_huge
print cumulative_sum

これは小さなリストでは問題なく機能しますが、大きなリストでは無限大になるか、実行時エラーがスローされます。これを行うより良い方法はありますか?すべての組み合わせを取得するより良い方法は? または、xrange を間違った方法で使用していますか?

これを Python 2.7 と Pypy 2 で試しました。

編集: @famagusta のおかげで xrange を削除しましたが、問題はまだ残っています

import itertools

# example inputs
list_small = [1, 2, 3]
list_medium = [444, 666, 242]
list_huge = [1680, 7559, 5573, 43658, 530, 11772, 284, 50078, 783, 37809, 6740, 37765, 74492, 50078, 783, 37809, 6740, 37765, 74492]

max_element = max(get_input_stones)
combo_list = range(0, max_element + 1)

cumulative_sum = 0
for current_combination in itertools.product(*combo_list):
    # now I need to do some calculations to the current combination
    # e.g. get sum of all combinations, this is just an example
    cumulative_sum += sum(current_combination)

    # another example
    # get XOR sum of current combination, more at https://en.wikipedia.org/wiki/Exclusive_or
    print reduce(operator.xor, current_combination, 0)

# runs fast for list_small, then takes some time for list_medium and then takes ages for list_huge
print cumulative_sum
4

1 に答える 1

1

このようなネストされたリストを生成すると、メモリ制限の問題が発生する可能性があります。サブリストを繰り返し生成する代わりに、リスト内の最大数から生成されたスーパー リストを 1 つだけ使用できます。小さな要素が停止する場所にインデックスを保存するだけです。

たとえば、[1, 6, 10] - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 6, 10]

2 番目のリストは、計算のために関心のあるサブリストを抽出するために最初のリストのどこで停止するかを示します。

これにより、スペースを節約できます。

list_small = [1, 2, 3]
list_medium = [444, 666, 242]
list_huge = [1680, 7559, 5573, 43658, 530, 11772, 284, 50078, 783, 37809, 6740, 37765, 74492, 50078, 783, 37809, 6740, 37765, 74492]

max_element = max(list_huge)   # being lazy here - write a max function
combo_list = range(0, max_element + 1)  # xrange does not support slicing

cumulative_sum = 0
for element in list_huge:
    cumulative_sum += sum(combo_list[:element])

print(cumulative_sum)
于 2016-08-25T09:45:56.903 に答える