【问题标题】:Python: printing characters - nested loop or joining a string?Python:打印字符 - 嵌套循环或加入字符串?
【发布时间】:2016-04-19 10:10:19
【问题描述】:

假设我有一个列表:

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

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

其中一种方法更有效还是更推荐?

这个:

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

或者这个:

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

【问题讨论】:

    标签: python arrays string


    【解决方案1】:

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

    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
    

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

    无论如何,在我看来,您正在进入无用的过早优化。你确定你真的需要这样的效率吗?

    【讨论】:

      【解决方案2】:

      两者都不是“更有效”,没有上下文。

      嵌套循环适用于任何城市列表,无论多大,只要您首先设法构建它。它有额外的额外开销,即运行一个反复重新初始化内循环的外循环。

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

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

      【讨论】:

        【解决方案3】:

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

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

        因为每次调用 print 都有相当多的开销,所以尽可能少地使用通常是好的(在这种情况下是一个)。

        【讨论】:

          【解决方案4】:

          @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 和原始版本中,数字变化很大。在我做的运行中,有时第一种方法更快,有时是第二种方法。这告诉我它们实际上是相同的。没有统计学上的显着差异。这些变化是由于机器上发生的其他事情造成的。

          ^相对而言,因为 100K 迭代的毫秒差异意味着每次迭代只有纳秒,这不值得你花时间。我已经花费了数十亿纳秒来写这篇文章。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-29
            • 2017-03-09
            • 1970-01-01
            相关资源
            最近更新 更多