【问题标题】:Print and for loop in one line在一行中打印和 for 循环
【发布时间】:2018-10-17 03:21:00
【问题描述】:

对于这个简单的代码块,有没有其他替代方法:

n = int(input())
for i in range(n):
    print(i**2)

我试过了:

print(i**2 for i in range(int(input())))

它需要一个输入,但给出以下错误:

<generator object <genexpr> at 0x00000000032D3E60>

我的问题与this qs 有点不同。无论我是否需要在换行符中打印它们,qs 都有助于打印列表中的项目。

【问题讨论】:

  • 不是错误,这是您传递给print 的对象的表示。您可以执行[print(i**2) for i in range(int(input()))] 之类的操作,但通常不鼓励使用列表推导来解决副作用; for i in range(int(input())): print(i**2) 很好。

标签: python python-3.x


【解决方案1】:

正如 Jon 和 Patrick 提到的,这不是错误,当您打印生成器表达式的 __repr__ 时会发生这种情况。

所以你只需要"splat"那个生成器。 :)

print(*(i**2 for i in range(int(input()))), sep='\n')

演示输出

10
0
1
4
9
16
25
36
49
64
81

在那个演示中,我在input 提示符处输入了10


在 cmets 中,我想知道 i * i 的速度与 i ** 2 相比如何。在我的旧 2GHz 32 位单核机器上,运行 Python 3.6.0,i * ii ** 2 快大约 3 或 4 倍。这是一些timeit 代码。

from timeit import Timer

commands = {'mul' : 'num * num', 'pow' : 'num ** 2'}

def time_test(num, loops, reps):
    timings = []
    setup = 'num = {}'.format(num) 
    for name, cmd in commands.items():
        result = Timer(cmd, setup).repeat(reps, loops)
        result.sort()
        timings.append((result, name))

    timings.sort()
    for result, name in timings:
        print(name, result)

loops, reps = 100000, 3
num = 1
for _ in range(10):
    print('num =', num)
    time_test(num, loops, reps)
    num <<= 1

输出

num = 1
mul [0.02114695899945218, 0.02127135100090527, 0.02303983199817594]
pow [0.08504067399917403, 0.08687452600133838, 0.12349813100081519]
num = 2
mul [0.02089159800016205, 0.021789606998936506, 0.02889108999806922]
pow [0.08612996800002293, 0.09132789800059982, 0.09559987299871864]
num = 4
mul [0.021155500999157084, 0.02333696799905738, 0.028521009000542108]
pow [0.08492234799996368, 0.08499632499660947, 0.08537705599883338]
num = 8
mul [0.02173021600174252, 0.021955170999717666, 0.02823427400289802]
pow [0.08423048700205982, 0.08541251700080466, 0.08654486299928976]
num = 16
mul [0.02176373900147155, 0.02222509399871342, 0.02816650199747528]
pow [0.08528696699795546, 0.09080051600176375, 0.0968476650014054]
num = 32
mul [0.03118283900039387, 0.03388790600001812, 0.03745272100059083]
pow [0.0943321790000482, 0.09484523300125147, 0.09691544299857924]
num = 64
mul [0.030481540998152923, 0.03292956899895216, 0.03887743200175464]
pow [0.09454960600123741, 0.09569520199875114, 0.09926063899911242]
num = 128
mul [0.030935312999645248, 0.031198748001770582, 0.03733277300125337]
pow [0.09531564099961543, 0.09669112700066762, 0.09679062199938926]
num = 256
mul [0.03280377900227904, 0.03324341500047012, 0.04479783699935069]
pow [0.09439349899912486, 0.09439918999851216, 0.09548852000079933]
num = 512
mul [0.03275527599907946, 0.03428718699797173, 0.038492286003020126]
pow [0.10492119499758701, 0.10698100599984173, 0.13057717199990293]

【讨论】:

  • 这正是我们所需要的,根据需要在换行符中打印出来。
  • @michaelpetronav 很高兴你喜欢它。 :) 顺便说一句,我可能会使用i*i 而不是计算平方,而不是通用的幂运算符。打字稍微短一些,但我不知道执行速度是否有明显差异。
  • i*i 和 i**2 的速度比较测试在这里问可能是件好事。我试图检查大数字,但无济于事。
  • @michaelpetronav 在我的机器上,i * ii ** 2 快大约 3 或 4 倍。我在答案的末尾添加了一些timeit 代码和输出。
【解决方案2】:

您应该将表达式包装到 [] 中以获得 list comprehension

print([i**2 for i in range(int(input()))])

如果您想逐行打印结果,只需使用extended iterable unpacking operator

print(*[i**2 for i in range(int(input()))], sep = '\n')

【讨论】:

  • @jonrsharpe Mihai 已修复该问题。
【解决方案3】:

这没有错误。您在 print(...) 中的语句是一个生成器表达式 - 它的字符串表示被打印 - 这就是您认为的“错误”。

您可以通过将其输入列表来转换它:

print(list(i**2 for i in range(int(input()))))

或通过迭代:

print(*(i**2 for i in range(int(input()))))

最后一个将导致输出(input() = 5):

0 1 4 9 16

因为生成器的每个结果都被传递给 print 并使用默认的 sep=' ' 进行打印,您可以将其更改为 '\n' - 请参阅 PM 2Ring 的帖子

【讨论】:

    【解决方案4】:

    这会像您的代码一样将每个 i**2 打印在单独的行上:

    print('\n'.join(str(i**2) for i in range(int(input()))))
    

    【讨论】:

    • 顺便说一句,传递.join 一个列表组合实际上比一个生成器表达式更有效,因为它必须扫描要连接的字符串集合两次:第一次确定目标的总大小字符串,第二次扫描执行复制。因此,如果您向它传递一个 gen exp,它必须保存 gen exp 的输出,以便它可以执行这 2 次扫描。
    猜你喜欢
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    相关资源
    最近更新 更多