#python #python-2.7 #permutation #combinatorics
#python #python-2.7 #перестановка #комбинаторика
Вопрос:
Я хочу вычислить все возможные способы построения двоичного списка длиной n со следующей строкой
combinations = map(list, itertools.product([0, 1], repeat=n))
Это отлично работает с низкими n, но я хочу вычислить это для больших n (т. Е. Значений между 25-35). Есть ли лучший и более эффективный способ создания этого списка?
Комментарии:
1. Мне нужен список списков, и в любом случае это не работает на моем компьютере, ошибка памяти для большого n.
2. Какова конечная цель? Если вам не нужны все значения сразу, почему бы просто не сохранить итератор, а не
map
списки?3. В чем собственно проблема? Ошибка памяти? Пожалуйста, предоставьте вывод ошибки
4. Эта проблема принципиально экспоненциальна во времени и пространстве (если вы хотите фактически хранить все списки в памяти). Извините, вы мало что можете сделать.
Ответ №1:
Просто создайте список «лениво», чтобы не сохранять все сразу в памяти:
n = some-largish-value
for i in itertools.product([0, 1], repeat=n):
result = do_something_with(list(i))
Ответ №2:
Вы пытаетесь найти все комбинации 0 и 1 для n членов. Общее количество таких комбинаций будет 2**n
. Для n=30
, всего таких комбинаций 1073741824
. Огромный, не так ли?
Чтобы избавиться от ошибки памяти, вы должны использовать генератор, который yield
динамически комбинирует вместо того, чтобы сохранять их в виде списка. Кроме того, поскольку это комбинация только 0 и 1. Почему бы не печатать двоичные числа от 0
до '1'*n
?
Ниже приведен итератор для достижения этой цели как:
def binary_combinations(num):
my_binary_string = '1'*num
my_int_num = int(my_binary_string, 2)
format_string = '{' ':0{}b'.format(num) '}'
for i in xrange(my_int_num):
yield format_string.format(i)
else:
raise StopIteration('End of Memory Issue!')
Чтобы выполнить это, выполните:
>>> for i in binary_combinations(3):
... print i
...
000
001
010
011
100
101
110
Здесь n = 3
. Теперь вы можете использовать его с n = 30, 40, .. ИЛИ как угодно;)
Ответ №3:
Нет, если вам действительно нужен список списков, тогда ваш код почти настолько эффективен, насколько это возможно. Ваша проблема заключается в размере списка, а не в том, как вы его вычисляете.
Вы понимаете, что для n = 35 у вас будет 1 202 590 842 880 элементов? Большинство (если не все) настольных компьютеров не могут хранить так много целых чисел python в памяти.