Initial public offering auction
Use the function name given in the problem:
def getUnallottedUsers(bids, totalShares):

The problem doesn't provide any information about the likelihood of there being enough shares for all bidders, so IMO the first for-loop is an example of premature optimization.
Use constants instead of &quot;magic numbers&quot;.  Use meaningful names.  Take a look at PEP8 about common formatting conventions.  These things go a long way in making code readable.
USERID = 0
SHARES = 1
PRICE = 2
TIME = 3

bids.sort(key=lambda bid:(-bid[PRICE], bid[TIME]))

for index, bid in enumerate(bids):
    totalShares -= bid[SHARES]

    if totalShares &lt;= 0:
        break

Answer the question that was asked: &quot;The function must return a list of integers, each an id for those bidders who receive no shares, sorted ascending&quot;
return sorted(bid[USERID] for bid in bids[index + 1:])

All together:
USERID = 0
SHARES = 1
PRICE = 2
TIME = 3

def getUnallottedUsers(bids, totalShares):
    bids.sort(key=lambda bid:(-bid[PRICE], bid[TIME]))

    for index, bid in enumerate(bids):
        totalShares -= bid[SHARES]

        if totalShares &lt;= 0:
            break

    return sorted(bid[USERID] for bid in bids[index + 1:])

Or use an iterator:
    bids = iter(bids)
    while totalShares &gt; 0:
        price = next(bid)[PRICE]
        totalShares -= price

    return sorted(bid[USERID] for bid in bids)