Home > OS >  I'm printing a lot of items in a for loop, but the for loop isn't fast enough
I'm printing a lot of items in a for loop, but the for loop isn't fast enough

Time:04-18

I'm trying to print a lot of strings from a list, in a for loop. It works fine but it's too slow, is there any way to make it faster.

import time
import os

board = {
        1:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        2:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        3:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        4:[' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        5:['#','#','#','#','#','#','#','#','#','#','#','#'],
}
while True:
        os.system('clear')
        v = 1
        while v < 6:
                or i in board[v]:
                        print(i, end = ' ')
                v  = 1
                print('')

In the end it works fine, but it prints too slowly (It makes the text flash). Is there any way to speed it up so it looks consistent?

CodePudding user response:

There is a whole story on refreshing the screen in games. The idea is not to clear the screen between frames.

import time
import os
import atexit

def clear():
  print ("{}[2J{}[;H".format(chr(27), chr(27)), end="")
  return

def move_to(row,col):
  print("{}[{};{}H".format(chr(27), row, col), end="")
  return

def hide_cursor():
  print('{}[?25l'.format(chr(27)), end="")
  return

def show_cursor():
  print('{}[?25h'.format(chr(27)), end="")
  return

atexit.register(show_cursor)

board = {
        1:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        2:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        3:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        4:[' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
        5:['#','#','#','#','#','#','#','#','#','#','#','#'],
}
clear()
hide_cursor()
while True:
        move_to(0,0)
        v = 1
        while v < 6:
                for i in board[v]:
                        print(i, end = ' ')
                v  = 1
                print('')
show_cursor()

then you can refresh only parts of the screen which have changed.

This only works where terminal supports ANSI Escape sequences but that's seems ok since you already use "clear".

CodePudding user response:

The text flashing happens also with C while using a small matrix like yours (I have the same problem here).


I don't think this will optimize your code so much, but I would suggest you to use a list over a dict in this scope:

board = [0,
    [' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
    [' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
    [' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
    [' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
    ['#','#','#','#','#','#','#','#','#','#','#','#']
]

This will do the same thing, a dict is useless in this case since you are using ints as keys.

CodePudding user response:

did you try comprehension?

board = {
    1: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    2: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    3: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    4: [' ', '@', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    5: ['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
}
[[print(i, end=' ') for i in board[v   1]] for v in range(len(board))]

CodePudding user response:

If the board state really is managed this way, you can print line by line rather than char by char:

for row in board:
    print(''.join(row))

Or calculate the whole block and issue a single print command immediately after the clear, and only if it actually changed.

def format_board(board):
    return '\n'.join(''.join(row) for row in board)

while True:
    if format_board(board) != board_lastchange_string:
        os.system('clear')
        print(format_board(board))

# if you update the board somewhere, save
# `format_board(board)` to `board_lastchange_string`
  • Related