То, как вы написали это выше, на самом деле хороший идиоматический питон. Если мы проанализируем алгоритм, то обнаружим, что он по сути делает это:
- Составление списка элементов, удовлетворяющих предикату. (Растет линейно с n)
- Выбор случайного элемента из этого списка. (Постоянное время)
Единственный другой способ сделать это - выбрать элемент случайным образом, решить, удовлетворяет ли он предикату, и еще раз выбрать, если нет. Этот алгоритм немного сложнее. В случае, когда 90% списка удовлетворяет предикату, это будет выполняться намного быстрее, чем ваше решение. В случае, когда только 10% списка удовлетворяет предикату, он на самом деле будет работать намного медленнее, поскольку есть большая вероятность, что он случайным образом выберет данный элемент и проверит, удовлетворяется ли предикат для этого элемента более одного раза. Теперь вы можете подумать о запоминании своего предиката, но вы все равно будете выбирать много случайных данных. Это сводится к следующему: если ваше решение не особенно подходит для ваших данных, придерживайтесь его, потому что это здорово. Лично я бы переписал это так:
intlist = range(1,10)
randomeven = random.choice([i for i in intlist if i % 2 == 0])
Это немного более кратко, но будет работать точно так же, как ваш существующий код.