2015-04-05 50 views
1
def get_strings(letters, max_length): 
    for i in range(1, max_length + 1): 
     for value in product(letters, repeat=i): 
      yield "".join(value) 

comb = [i for i in get_strings(ascii_lowercase, 4)] 
print "# of possible combinations: %s" % len(comb) 

def perc(i, tot): 
    p = float(i) /float(tot) 
    return p * 100 

marker = [x for x in range(100) if x % 10 == 0] 
marker.pop(0) 

# make it 10:0, 20:0, 30:0, 40:0 and so forth... 
mark = dict(zip(marker, [0 for i in range(len(marker))])) 
print "BEFORE:" 
for i in marker: 
    print "%s percent index: %s" % (i, mark[i]) 

l = len(comb) 
for i,v in enumerate(comb): 
    p = perc(i, l) 
    ip = math.ceil(p) 
    if ip in marker: 
     mark[ip] = i 


print "AFTER:" 
for i in marker: 
    print "%s percent index: %s" % (i, mark[i]) 

OUTPUT:獲取指數

# of possible combinations: 475254 
BEFORE: 
10 percent index: 0 
20 percent index: 0 
30 percent index: 0 
40 percent index: 0 
50 percent index: 0 
60 percent index: 0 
70 percent index: 0 
80 percent index: 0 
90 percent index: 0 
AFTER: 
10 percent index: 47525 
20 percent index: 95050 
30 percent index: 142576 
40 percent index: 190101 
50 percent index: 237627 
60 percent index: 285152 
70 percent index: 332677 
80 percent index: 380203 
90 percent index: 427728 

我能與上面的代碼來做到這一點,但它似乎很繁瑣和大量的不必要的步驟(或者說可以合併或減少)。

任何簡化?

+0

什麼是get_strings?還有,你爲什麼使用'for i,v in enumerate(comb)'? – 2015-04-05 17:04:41

+0

@PadraicCunningham增加了get_strings – ealeon 2015-04-05 17:05:49

回答

2

讓我們逐個解決這部分。

首先,讓我們來簡化計算百分比

perc = lambda i, t: (i * t)/100 

現在讓我們來簡化你的計算

marker = xrange(10, 100, 10) 

現在讓我們來計算列表的長度的一定比例指數:

for i in marker: 
    print '%s percent index: %s' % (i, perc(i, len(comb)) 

就是這樣!


你可以進一步簡化上述簡明的三行:

perc = lambda i, t: (i * t)/100 
for i in xrange(10, 100, 10): 
    print '%s percent index: %s' % (i, perc(i, len(comb)) 

如果你真的需要將標記存儲在mark字典,使用字典理解

mark = {i: perc(i, len(comb)) for i in xrange(10, 100, 10)} 

這整個代碼的一部分可能是不必要的:

marker = [x for x in range(100) if x % 10 == 0] 
marker.pop(0) 

# make it 10:0, 20:0, 30:0, 40:0 and so forth... 
mark = dict(zip(marker, [0 for i in range(len(marker))])) 
print "BEFORE:" 
for i in marker: 
    print "%s percent index: %s" % (i, mark[i]) 

l = len(comb) 
for i,v in enumerate(comb): 
    p = perc(i, l) 
    ip = math.ceil(p) 
    if ip in marker: 
     mark[ip] = i 
1

您應該使用xrange,你的一些列表內涵也是不必要的:

from collections import OrderedDict 

def get_strings(letters, max_length): 
    return ("".join(value) for i in range(1, max_length + 1) 
      for value in product(letters, repeat=i)) 

comb = [i for i in get_strings(ascii_lowercase, 4)] 

print "# of possible combinations: {}".format(len(comb)) 

# use an OrderedDict to maintain order, create the keys using a start 
# of 10 and a step size of ten 
mark = OrderedDict.fromkeys(xrange(10, 100, 10),0,) 

# iterate over the items to avoid unnecessary lookups 
print "BEFORE:" 
for k, v in mark.iteritems(): 
    print "{} percent index: {}".format(k, v) 

l = len(comb) 
# use keys of dict 
for i in mark: 
    mark[i] = int(float(i) * l/100) 

print "AFTER:" 
for k,v in mark.iteritems(): 
    print "{} percent index: {}".format(k, v) 

沒有必要爲一個功能百分比計算,range不應該在python2中使用,除非你真的想要一個列表。