获取列表长度的某个百分比的索引

时间:2015-04-05 16:57:28

标签: python

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])

输出:

# 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

我能够使用上面的代码完成它,但它似乎非常乏味和许多不必要的步骤(或者更确切地说可以组合或减少)。

任何简化?

2 个答案:

答案 0 :(得分:2)

让我们逐一解决这个问题。

首先,让我们简化百分比计算

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

现在让我们简化您的marker计算

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 :(得分: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中使用,除非你真的想要一个列表。