У меня есть список многих элементов.
Мне нравятся два его элемента, a
и b
.
Я не знаю порядок списка и не хочу его сортировать.
Есть ли хороший однострочный вкладыш, который вернет True
, если a
встречается до b
и false в противном случае?
У меня есть список многих элементов.
Мне нравятся два его элемента, a
и b
.
Я не знаю порядок списка и не хочу его сортировать.
Есть ли хороший однострочный вкладыш, который вернет True
, если a
встречается до b
и false в противном случае?
ОК, поэтому эта проблема требует немного больше работы. Марк Байерс совершенно прав в том, что мой первый тест охватывал только случаи, когда результат был бы True
. Это особенно актуально, потому что для других решений нужны обработчики исключений. Поэтому я подробно рассмотрел:
stmts = {
"Mark Byers: ": "x = l.index(a) < l.index(b)",
"jcollado: ": """try:
x = bool(l.index(b, l.index(a)))
except ValueError:
x = False""",
"Greg Hewgill: ": """try:
x = b in l[l.index(a):]
except ValueError:
x = False"""
}
setups = ["a = 80; b = 90; l = list(range(100))",
"a = 5; b = 10; l = list(range(100))",
"a = 90; b = 80; l = list(range(100))",
"a = 10; b = 5; l = list(range(100))"]
import timeit
for se in setups:
print(se)
for st in stmts:
print(st, timeit.timeit(stmt=stmts[st], setup=se))
print()
приводит к:
a = 80; b = 90; l = list(range(100))
Mark Byers: 5.760545506106019
Greg Hewgill: 3.454101240451526 # Tie!
jcollado: 3.4574156981854536 # Tie!
a = 5; b = 10; l = list(range(100))
Mark Byers: 1.0853995762934794 # Close runner-up!
Greg Hewgill: 1.7265326426395209
jcollado: 1.0528704983320782 # Winner!
a = 90; b = 80; l = list(range(100))
Mark Byers: 5.741535600372806
Greg Hewgill: 3.623253643486848 # Winner!
jcollado: 4.567104188774817
a = 10; b = 5; l = list(range(100))
Mark Byers: 1.0592141197866987 # Winner!
Greg Hewgill: 4.73399648151641
jcollado: 4.77415749512712
Таким образом, коэффициент эффективности от jcollado-метода в основном поглощается стоимостью обработчика исключений (особенно если он срабатывает). Все три решения выигрывают (или связывают с победителем) половину времени, поэтому какой метод лучше всего работает с вашими фактическими данными, трудно сказать. Возможно, вы захотите пойти с тем, который легче всего читать.
В интересах разнообразия вы также можете:
b in l[l.index(a):]
Это будет True
, если a == b
. Если вы знаете, что a != b
,
b in l[l.index(a) + 1:]
Вы можете использовать list.index
:
l.index(a) < l.index(b)
Это, конечно, предполагает, что оба элемента присутствуют в списке.
Ответ от Mark Byers отлично работает, но он не будет очень эффективным, если список длинный, и оба элемента близки к концу.
Чтобы перемещаться по списку один раз, вы можете использовать это:
l.index(b, l.index(a))
Это однострочный шрифт по мере необходимости, но вам все равно нужно зафиксировать исключение ValueError
.