【问题标题】:How can I make this repeat forever?我怎样才能让这个永远重复?
【发布时间】:2014-08-11 16:59:36
【问题描述】:

我有这个地形生成器,在我看来非常高效。我只是不能让它永远打印。这是我拥有的当前代码:

import random
print(' '.join([random.choice(['#','o','~','*']) for i in range(10000)]))

我尝试这样做,但我收到了SyntaxError

import random
print(' '.join([random.choice(['#','o','~','*']) while True]))

我怎样才能让它永远重复?我还希望在每个字符的打印之间有 0.05 秒的延迟。如果您可以将其保持在最多两行,那就太酷了。如果你不能,那没关系。谢谢! 注意:不是关于gamedev的,我只是碰巧使用.join作为地形生成器。

【问题讨论】:

  • 您无法使用while 进行列表理解!为什么不只使用标准循环?
  • random.choice('#o~*') 更短(也许更清晰?)
  • 您最好花更少的时间尝试用尽可能少的字符来实现所有内容,而花更多的时间思考您实际想要实现的目标。硬盘比时间便宜。只需构建一个标准的生成器函数,并在需要时调用它。

标签: python loops random


【解决方案1】:

好吧,如果你想要字符之间的延迟,你不能使用join(),因为这会给你一个字符串而不是一个“字符生成器”。

如果您打算使用“无限”生成器,出于同样的原因,您也不能使用join()

这个怎么样:

import random
import sys
import time
while True:
    print(random.choice("#o~*"), end="", flush=True) # Python 3.3 and up
    time.sleep(0.05)

【讨论】:

  • sys.stdout.write(..)? (因为您已经在调用flush ..)
  • 当我运行它时,我得到一个SyntaxError。这是为 python 3 构建的吗?
  • @SomeGuy:是的,因为您使用的是 Python 3 语法(print 作为函数)和range 而不是xrange,我认为这是您的目标版本。跨度>
  • @TimPietzcker 哎呀,我想我没有意识到我刚刚在我的 python 2.x 编辑器中重新编写了这个。
  • 在最新版本的 Python 中,print 具有关键字参数 flush。您可以将代码长度减少两行。
【解决方案2】:

你可以试试这个简化版的代码:

import random, sys, time
while True: sys.stdout.write(random.choice('#o~*') + ' '); time.sleep(0.05)

【讨论】:

  • 你试过了吗?它打印一个随机字符、一个空格、2sys.stdout.write() 的结果)和一个换行符。无限重复。
  • 你是在 IDLE 还是命令行中运行的?如果是这样,解释器会将sys.stdout.write(random.choice('#o~*') + ' ') 的结果显示为两个(意味着写入了两个字节)。如果你把它作为一个程序运行,你就不会遇到这个问题。
【解决方案3】:

这是一种新方法。

自己动手

import random
import time

class GenerateRandomChar(object):
    def __init__(self, charlist):
        self.charlist = charlist
    def __next__(self):
        return random.choice(self.charlist)

terrain_tiles = GenerateRandomChar("#o~*")
while True:
    print(next(terrain_tiles), end='')
    time.sleep(0.05)

此外,如果您正在构建地图,您可能需要考虑以下内容:

class Map(list):
    def __init__(self, terrain_tiles, WIDTH=12, HEIGHT=12):
        self.WIDTH = WIDTH
        self.HEIGHT = HEIGHT
        self.terrain_tiles = GenerateRandomChar(terrain_tiles)
        for y in range(self.HEIGHT):
            self.append([next(self.terrain_tiles) for x in range(self.WIDTH)])
    def __str__(self):
        return "\n".join([" ".join([tile for tile in row]) for row in self])

>>> map_ = Map("~o#*")
>>> print(map_)
o o o o o o ~ ~ # ~ ~ ~
# # # o o # o # o # * #
~ o # * ~ # o # * ~ # ~
o * o o o * # o # o # *
# * o # # # * o ~ * # #
# ~ o ~ * # # ~ o o ~ ~
~ * # # o ~ o * # # ~ o
# o * o o * o * ~ ~ o *
# # * * ~ ~ ~ * # * # o
o o ~ ~ # * ~ ~ * ~ * o
~ * ~ ~ * # * * ~ # o #
* o ~ # ~ # ~ ~ o o o o

【讨论】:

    【解决方案4】:

    你不能在你的打印函数中有一个循环,你必须把你的打印函数放在一个循环中,例如:

    while True:
        print random.choice(['#','o','~','*']),
    

    【讨论】:

    • 嗯,你可以这样做...但是为什么join
    • print(random.choice(['#','o','~','*'])) 就足够了。要不打印\n,请添加, end=""
    • 哦,让我来解决这个问题,我只是专注于说明您不能在打印语句中嵌入循环,我忘了检查实际的打印语句。 (感谢您接受!)
    • 很抱歉,因为我更适合 C++,所以这是一个很难改掉的习惯。感谢您向我指出这一点。
    • 你忘记了random.choice()末尾的逗号。
    【解决方案5】:

    带有随机符号的无限迭代器:

    import itertools
    it = (random.choice(['#','o','~','*']) for i in itertools.repeat(""))
    

    正如一些人评论的那样,join() 不会帮助您,因为它会在返回之前生成整个字符串。你可以试试(Python 3):

    [print(char, end="") for char in it] # not such a good idea
    

    for char in it: print(char, end="")
    

    【讨论】:

      【解决方案6】:

      您可以使用生成器:

      from itertools import repeat
      import random
      from time import sleep
      import sys
      
      gen = (random.choice(['#','o','~','*']) for _ in repeat(None))
      for x in gen:
          print x,
          sys.stdout.flush()
          sleep(0.05)
      

      【讨论】:

      • itertools 可以做任何事情 itertools.repeat
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 2019-11-12
      相关资源
      最近更新 更多