2016-03-19 3 views
1

Я хотел бы перебрать все списки/кортежи длины n с элементами из -s ... s. В настоящее время я делаю это с:Как перебирать списки из середины

for k in itertools.product(range(-s,s+1), repeat = n): 
    #process k and maybe print out the result 

Однако это не полезно для меня, поскольку есть огромное количество таких кортежей и мой код никогда не может завершиться. Я бы очень хотел начать сначала с самых интересных. В этом случае порядок я хотел бы для итерации:

  1. Все кортежи, которые содержат только 0 (есть только один)
  2. Все кортежи, которые содержат только 0, 1 и -1 за исключением тех кортежей мы имеем уже видел.
  3. Все кортежи, содержащие только 0, 1, -1, 2 и-2, исключая те кортежи, которые мы уже видели.
  4. И так далее ...

Как можно это сделать?

+1

разделить его пополам, реверс первый и 'почтовый индекс()' их? Не уверен, что я понимаю, что именно вы ищете. – TigerhawkT3

+0

@ TigerhawkT3 Я хотел бы перебирать списки в описанном мной порядке. Для каждого списка итерации я буду запускать некоторую функцию и иногда распечатывать результат. В целом код никогда не может завершиться, поэтому я хочу сделать их в правильном порядке. – Anush

ответ

1

Значит, ваш код будет со списком намного дороже сортировки?

Затем вы можете отсортировать список из этих списков с аргументом key. То, что вы называете списком, - это кортежи, верно? По крайней мере, в моем python 2.7 itertools. Я бы преобразовал их в массивы, так как я думаю, что вы не можете использовать abs в противном случае. Тогда функция сортировки:

lists.sort(key = lambda t: np.max(np.abs(np.array(t)))) 

Это работает достаточно быстро?

+0

Существует (2s + 1)^n разных списков. Я не могу позволить себе их всех, а потом сортировать. Вот почему я хочу перебирать их в разумном порядке. – Anush

+1

, так что вы хотите * сделать * их в разумном порядке. Тогда почему вы не начинаете с s = 0, составляете списки, сохраняете их и затем вычитаете из списков s = 1 (вы можете сделать набор «set» и substract, поскольку кортежи неизменяемы) – Ilja

+0

Две вещи. Я не хочу хранить огромное количество кортежей/списков, а во-вторых, вычитание будет дорогостоящим. Было бы намного лучше просто перебрать их в правильном порядке. – Anush

3

Как об этом:

import itertools 

def sorted_tuples(length, max_s): 
    nums = [0] 
    for s in range(max_s): 
     for p in itertools.combinations_with_replacement(nums, length): 
      if s in p or -s in p: 
       yield p 
     nums = [-(s+1)] + nums + [s+1] 

for i in sorted_tuples(3,2): 
    print(i) 

# prints the following 
(0, 0, 0) 
(-1, -1, -1) 
(-1, -1, 0) 
(-1, -1, 1) 
(-1, 0, 0) 
(-1, 0, 1) 
(-1, 1, 1) 
(0, 0, 1) 
(0, 1, 1) 
(1, 1, 1) 
+0

Должна быть ошибка. Если я делаю 'для i в sorted_tuples (9,4):' и смотрю на вывод, диапазон значений от -3 до 3. Поэтому я должен получить 7^9 = 40353607 строк вывода, но вместо этого получаю 5005. – Anush