I'm not sure why you would want to do this but anyways. Lets say you start your ICO at block 4,900,900 and continue until block 4,900,999. After you conclude the ICO, you could run a python script that searches the transaction history in between those blocks, calculating the total amount of ether sent from each address. Afterwards, you can have the same python script calculate how many tokens each person is to receive, and then utilizing web3py (or another web3 library) you can contact your token contract, and tell it to send X coin to Y address.
That being said I have no idea why you wouldn't just write a smart contract to do an ICO. Not only would it probably require significantly LESS development time, testing, and lines of code but it would all be handled autonomously via on-chain processes through the use of smart contracts.
Also I would never invest in an ICO where the recipient address is a plain old address and not a contract as it would look like a scam just an FYI. I imagine many other people will feel the same way.
And yes its entirely possible to tell an address, from a contract address. You could use the assembly opcode
extcodesize(addr) amongst other tactics.
I can't remember the name but there was an ICO that scammed it's investors and the recipient address was a plane old address not a contract address.