The names of the files returned do not bear any special significance. If you need to associate files returned with information in the original request, you have to maintain association in your Python script. This is exactly what the official Python client does.
A request may produce several files. Incremental query requests typically produce one or a few files, snapshot query requests typically produce more files. Specifics largely depend on the size of the table requested, the distribution of the data, the size of the data retrieved, etc. You should not make hidden assumptions about the number of files returned; your Python script should iterate over all the files returned, and process them the same way.
Each file has a header, and contains zero or more records. If the file contains no records other than the header, your script should simply skip the file. DAP distributes tasks associated with a request to multiple nodes, which work independently. If one of the tasks finds no records matching the query in the data range it has been preliminarily assigned, it will produce an empty file.
While it might be helpful to have more structure to file names, AWS S3 does not support rename on objects. (AWS S3 is the underlying data store used in passing data for query results.) Unfortunately, a nice name is not always known beforehand when tasks spin up, and we must go with some name to let tasks work independently without conflict.
All of the above features are already implemented in instructure-dap-client, the Python client library provided by Instructure. I recommend reading through the classes and functions exposed in the module dap.api. Even if you decide to roll your own integration, you may be inspired by how DAP client library implements data retrieval. (Data processing will change in major ways with the upcoming new version of the client. However, the way the client interacts with DAP API and downloads files is going to remain largely the same.)