Seria bom ter suporte completo para métodos definidos para dicionários (e não para a bagunça profana que estamos enfrentando no Python 3.9), para que você possa simplesmente "remover" um conjunto de chaves. No entanto, desde que não seja esse o caso, e você tenha um dicionário grande com um número potencialmente grande de chaves para remover, convém saber sobre o desempenho. Então, eu criei um código que cria algo grande o suficiente para comparações significativas: uma matriz de 100.000 x 1000, portanto, 10.000,00 itens no total.
from itertools import product
from time import perf_counter
# make a complete worksheet 100000 * 1000
start = perf_counter()
prod = product(range(1, 100000), range(1, 1000))
cells = {(x,y):x for x,y in prod}
print(len(cells))
print(f"Create time {perf_counter()-start:.2f}s")
clock = perf_counter()
# remove everything above row 50,000
keys = product(range(50000, 100000), range(1, 100))
# for x,y in keys:
# del cells[x, y]
for n in map(cells.pop, keys):
pass
print(len(cells))
stop = perf_counter()
print(f"Removal time {stop-clock:.2f}s")
10 milhões de itens ou mais não é incomum em algumas configurações. Comparando os dois métodos na minha máquina local, vejo uma ligeira melhora ao usar mape pop, presumivelmente por causa de menos chamadas de função, mas ambas demoram cerca de 2,5 segundos na minha máquina. Mas isso empalidece em comparação com o tempo necessário para criar o dicionário (55s), ou incluindo verificações dentro do loop. Se isso for provável, é melhor criar um conjunto que seja uma interseção das chaves do dicionário e do seu filtro:
keys = cells.keys() & keys
Em resumo: deljá está fortemente otimizado, portanto, não se preocupe em usá-lo.