2015-10-06 18 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,...。所以它是指數,但只有直到它在下一個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]