2015-10-06 3 views
3

Я пытаюсь создать функцию, которая будет создавать список на основе шаблона в зависимости от длины другого списка. Я не уверен, как это сделать из-за характера шаблона. Я пытаюсь сделать что-то подобное, что будет вести себя как:Использование шаблона для создания списка

len(a_list) = 50 

created_pattern_a_list = [1,2,4,8,10,20,40] 

len(b_list) = 9000 

created_patten_b_list = [1,2,4,8,10,20,40,80,100,200,400,800,1000,2000,4000,8000] 

Так шаблон я хочу 1,2,4,8,10, ... .so это экспоненциальная, но только до него на следующая мощность 10, затем она начинается с этой мощности 10. Я не уверен, как сделать функцию, которая могла бы это сделать. Что-то вроде:

def create_patten_list(a_list): 
    reff_list = [1,2,4,8,10,20,40,80,100,200,400,800,1000,2000,4000,8000,10000] 
    corr_list = [a for a in reff_list if a <= len(a_list)] 
    return corr_list 

Но длина a_list может быть гораздо больше, чем 10000, так что я не могу просто использовать список по умолчанию установленной длины, как это. Есть ли лучший способ установить такой шаблон?

ответ

3

Я уверен, что это не самое изящное решение, но учтите следующее: Повторяющаяся часть вашего шаблона - всего 1, 2, 4 и 8. Остальное - всего лишь порядок.

def get_pattern(length): 
    template = [1, 2, 4, 8] 
    output = [] 
    i = 0 
    while True: 
     num = template[i%4] * 10**(i//4) 
     if num > length: 
      break 
     output += [num] 
     i += 1 
    return output 

Итак:

>>> get_pattern(5000) 
[1, 2, 4, 8, 10, 20, 40, 80, 100, 200, 400, 800, 1000, 2000, 4000] 
0

Вы можете сделать это:

from itertools import cycle 
def get_pattern(n): 
    for e,i in enumerate(cycle((1,2,4,8))): 
     val = i*(10**(e//4)) 
     if val > n: return 
     yield val 

так

>>>list(get_pattern(5000)) # or len(a_list) instead of 5000 
[1, 2, 4, 8, 10, 20, 40, 80, 100, 200, 400, 800, 1000, 2000, 4000] 
0

Как об этом:

def create_pattern_list(a_list): 
    def gen(n): 
     num = 1 
     step = 10 
     while num <= n: 
      yield num 
      num = num * 2 
      if num/step: 
       num = step 
       step = step * 10 

    return list(gen(len(a_list))) 
0

Если вам нравится злоупотреблять itertools, вы можете использовать это решение.

from itertools import count, repeat, cycle, izip 
def get_pattern(length): 
    repeated_multiplier = (y for x in count(0) for y in repeat(x, 4)) 
    repeat_1248 = cycle([1, 2, 4, 8]) 
    number_generator = izip(repeat_1248, repeated_multiplier) 
    values = [] 
    while True: 
     x = next(number_generator) 
     x = x[0] * 10**x[1] 
     if x > length: 
      break 
     values.append(x) 
    return values 
0

Следующие даст вам результаты, вам нужно:

from itertools import takewhile, cycle 

def create_patten_list(a_list): 
    length = len(a_list) 
    sequence = [1,2,4,8] 
    return [x[1] * 10 ** (x[0] // 4) for x in takewhile(lambda x: x[1] * 10 ** (x[0] // 4) <= length, enumerate(cycle(sequence)))] 

print create_patten_list(range(50)) 
print create_patten_list(range(9000)) 

Давать следующий вывод:

[1, 2, 4, 8, 10, 20, 40] 
[1, 2, 4, 8, 10, 20, 40, 80, 100, 200, 400, 800, 1000, 2000, 4000, 8000] 
Смежные вопросы