from concurrent.futures import ThreadPoolExecutor, as_completed

def executor(func, kwargs_list: list[dict],num_workers: int = 1):
    results = [None] * len(kwargs_list)
    if num_workers <= 1 or len(kwargs_list) <= 1:
        for i, kwargs in enumerate(kwargs_list):
            results[i] = func(**kwargs)
    else:
        with ThreadPoolExecutor(max_workers=num_workers) as pool:
            future_to_idx = {
                pool.submit(func, **kwargs): i
                for i, kwargs in enumerate(kwargs_list)
            }
            for future in as_completed(future_to_idx):
                i = future_to_idx[future]
                results[i] = future.result()

    return results


