如何在Python特定puzz中将循环转换为列表理解

2024-10-01 22:25:22 发布

您现在位置:Python中文网/ 问答频道 /正文

如果您给它一个数字N,它将生成1234…N或N…4321,但输出不是作为字符串,而是作为数字。我想把中间的循环转换成列表理解,但在尝试时遇到了麻烦。在

下面是运行的代码(用Python2.7编写:

def findTens(N):
    # counts number of tens in a number: examples:  
    #   * 100 & 113 would both return 2
    #   * 9 returns 0
    #   * 14 returns 1

    incrementer = 1
    while True:
        if N - 10**incrementer < 0:
            break
        else:
            incrementer += 1

        if incrementer == 100:  
            break   # debugging condition
    return incrementer - 1

def create_seqNum(N, reverse=False, showWork=False, returnDescr=False, divLength=100):
    '''create_seqNum() --> iput N, and get back a number built from the sequence of 1234...N
Arguments: reverse=True to get the sequence in revers, showWork=True to see numbers that add up to final,
returnDescr=True to print the answer in a sentence as well as returning it as a number.'''

    num = 0
    tensIncr = 0
    answer = 0
    Ntens = findTens(N)
    modifier = 0            # modifies counter when increment of 10 occurs
    if reverse == True:     # create range builder inputs
        rstart = 1
        rend = N+1
        rinc = 1
    else:
        rstart = N
        rend = 0
        rinc = -1
    for i in range(rstart, rend, rinc):
        itens = findTens(i)
        num = i * 10**tensIncr        
        tensIncr += 1 + itens
        pad = (Ntens - itens)
        if showWork == True:
            print(("For %d" + " "*pad + " Add: %d") %(i, num))    
        answer += num

    if showWork == True:
        print("#"*divLength)

    if showWork == True or returnDescr == True:
        print("Answer: %d" %answer)
        print("#"*divLength)

    return answer

这些测试用例都使用上述代码:

^{pr2}$

还请注意,我创建工作列表理解的尝试失败了,因为我在计算中取消了循环,并且使它能够得到它加起来的数字列表以及最终的总和(“showWork”选项)。但如果没有人能同时解决这两个问题,那么通过所有测试的最佳计算方案将被接受。在

万一有帮助的话,我尝试把它转换成失败的列表理解。如果有人能找到答案,希望从你的答案中学习,并认为其他人可能会发现这个有趣的谜题(至少我希望):

^{3}$

这一挑战的来源和背景:

在HackerRank上,他们让你简单地不使用字符串来解决N=123…N,他们接受一个简单的一行打印格式语句作为答案。虽然使用python3.x打印参数与解包列表相结合可以更有效地解决这个问题,但我对是否可以构建数字感兴趣,因为它是一个不需要进行任何字符串转换的数字。由于print()我认为在输出内容之前先将其转换为string,所以我觉得从纯学术的角度来看,这是一种更有趣的方法。在


Tags: ofto字符串answerintruenumber列表
3条回答

呃,那么,这看起来像是癌症,但我认为它有效

def get_seq(n):
    return sum([(m+1)*10**(m + [sum([k/10 for k in range(n)][:i+1]) for i in range(len([j/10 for j in range(n)]))][m]) for m in range(n)])

我不太清楚你的问题,但你在找这样的东西吗?在

def create_seqNum(num, reverse=False):
    final_num = 0
    x = [x for  x in range(1, num+1)]
    y = [y for y in range(num, 0, -1)]
    for i in range(0, num):
        print(x[i], y[i])
        final_num += x[i]* 10**(y[i]-1)

    return final_num

这可以在一行中完成(减去导入),不超过O(n)步,不需要编写单独的函数或循环,只需一个标准的map reduce。在

import math # to get math.log10
listofints = [1,2,3,10,12,19,99,100,101,50102030]
n = reduce(lambda x,y:[x[0]*(10**(y[1]+1))+y[0],0],map(lambda x:[x,int(math.log10(x))], listofints))[0]
print(n)

# the number 1231012199910010150102030

这使用一个标准的map-reduce方法来使用map修饰数字,然后将它们还原为一个数字。在

第一步:

^{pr2}$

获取整数列表,例如:

[1,2,3,10,12,19,99,100,101,50102030]

然后将它们转换为数字加上以10为底的对数对的列表:

[[1, 0], [2, 0], [3, 0], [10, 1], [12, 1], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]

然后,下一步是将该列表缩减为一个数字:

reduce(lambda x,y:[x[0]*(10**(y[1]+1))+y[0],0],...

为了做到这一点,你需要把它乘以足够的10次方,以腾出空间将下一个数相加。幸运的是,下一个数字显示它有多大。因此,将一对的数字(第一部分)乘以10乘以下一对(第二部分)的幂(1加上),然后加上第二对的数字(第一部分)。在

降幅如下:

[[1, 0], [2, 0], [3, 0], [10, 1], [12, 1], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[12, 0], [3, 0], [10, 1], [12, 1], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[123, 0], [10, 1], [12, 1], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[12310, 0], [12, 1], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[1231012, 0], [19, 1], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[123101219, 0], [99, 1], [100, 2], [101, 2], [50102030, 7]]
[[12310121999, 0], [100, 2], [101, 2], [50102030, 7]]
[[12310121999100, 0], [101, 2], [50102030, 7]]
[[12310121999100101, 0], [50102030, 7]]
[[1231012199910010150102030, 0]]

最后,最后一项是[1231012199910010150102030,0],所以取它的第一个元素,即1231012199910010150102030

更新

虽然整个map reduce是一个很好的习惯过程,但它在这里是过度的杀戮。这可以完全不使用map,只需使用reduce:

n = reduce(lambda x,y:x*(10**(int(math.log10(y))+1))+y,listofints)

相关问题 更多 >

    热门问题