Python:打印字符 - 嵌套循环还是连接字符串?

时间:2016-04-19 10:10:19

标签: python arrays string

我们假设我有一个清单:

cities = ['Berlin','London','Chicago']

我想单独打印该列表中的每个字母。

这些方法中的任何一种更有效还是推荐?

这:

for c in cities:
    for l in c:
        print l

或者这个:

for l in ''.join(cities):
    print l

4 个答案:

答案 0 :(得分:4)

"什么会更有效率"通常取决于操作系统和其他因素。但是,你可以做一个非常简单的基准测试:

cities = ['Berlin','London','Chicago']
import time

start = time.time()
for x in range(100000):
    for c in cities:
        for l in c:
            pass
end = time.time()
print "method 1: " + str(end-start)

start = time.time()         
for x in range(100000):     
    for l in ''.join(cities):
        pass
end = time.time()
print "method 1: " + str(end-start)

在带有python 2.7的Windows 8上,我得到了:

method 1: 0.218999862671
method 1: 0.141000032425

我相信大多数系统都会有类似的结果。

无论如何,听起来像你正在进入无用的过早优化。你确定你真的需要那么高的效率吗?

答案 1 :(得分:1)

没有上下文,“效率更高”。

嵌套循环可以在任何城市列表上工作,无论多大,只要你设法在第一时间构建它。它具有运行外部循环的额外开销,该循环重复地重新初始化内部循环。

第二个避免这种情况,但必须构建所有数据''.join(cities)的第二个副本以进行迭代。如果您的城市列表足够大或者您的环境在内存上足够短,那么在第一个城市成功的地方就会失败。它还会产生更多需要回收的垃圾。

除非你正在开发一个RAM非常有限的豌豆脑嵌入式系统,否则几乎可以肯定要么足够快地完成工作。一般而言,在具有GHz CPU和Gbytes RAM的现代PC系统中,效率不应该是您首要考虑的因素。一个例外是,您可以预测在RAM中组装所需的数据量有超出可用RAM量的危险,在这种情况下,避免使用完整的中间副本是值得的。另一个是你有不同顺序的算法,不能绝对保证数据量总是保持很小。在那种情况下,更喜欢低阶算法。当N变大时,O(N)在很大程度上胜过O(N ^ 2)!

答案 2 :(得分:1)

这是您应该测试的第三个选项(速度取决于您的使用案例):

print '\n'.join(''.join(cities))

因为每次打印调用都有相当多的开销,所以通常使用尽可能少(在这种情况下为1)。

答案 3 :(得分:0)

@ronen-ness 已经有 a good answer 指出对此的担心是过早的微优化。

我想补充一点,当尝试使用 Python 进行时间编码时,最好的选择是使用 timeit 而不是编写自己的基本测试。

重写看起来像:

import timeit

method1 = '''
for c in cities:
    for l in c:
        pass
'''

method2 = '''
for l in ''.join(cities):
    pass
'''
print(timeit.timeit(stmt=method1, setup="cities = ['Berlin','London','Chicago']", number=100000))
print(timeit.timeit(stmt=method2, setup="cities = ['Berlin','London','Chicago']", number=100000))
0.046141645999999994
0.04605432300000001

当我运行原来的结果就像

method 1: 0.09271407127380371
method 2: 0.09324479103088379

计时结果要快得多,因为 timeit 使用了适用于 Mac/Win/Linux 的正确时钟,它关闭了垃圾收集并从测量中消除了一堆其他开销。

然而 - 在 timeit 和 original 中,数字变化很大。在我所做的运行中,有时第一种方法更快,有时是第二种方法。这告诉我它们实际上是相同的;没有统计学上的显着差异。变化将是由于机器上发生的其他事情。

^相对而言,因为 100K 迭代的毫秒差异意味着每次迭代需要纳秒,这不值得您花时间。我花了几十亿纳秒才写这个。