Я не мог использовать другие ответы в моем случае. Вместо этого я использовал нативный таймер Java.
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// this code will be executed after 2 seconds
}
}, 2000);
У вас всегда будет цикл - кто-то может прийти с умным однострочником, который скрывает цикл внутри вызова map ()
или подобного, но он всегда будет там.
Я всегда предпочитаю иметь чистый и простой код, если только производительность не является основным фактором.
Вот, возможно, более питоническая версия вашего кода:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
for sublist in data:
if sublist[1] == search:
print "Found it!", sublist
break
# Prints: Found it! ['a', 'c']
Она выходит из строя цикл, как только он находит совпадение.
(Кстати, у вас есть опечатка в ['b''d']
.)
все вышеперечисленное выглядит хорошо
, но хотите ли вы сохранить результат?
если да ...
вы можете использовать следующий
result = [element for element in data if element[1] == search]
, затем простой
len(result)
позволяет узнать, было ли что-то найдено (и теперь вы можете что-то делать с результатами)
конечно это не обрабатывает элементы, длина которых меньше единицы (которые вы должны проверить, если не знаете, что они всегда больше, чем length 1, и в этом случае следует ли использовать кортеж? (кортежи неизменяемы))
если вы знаете, что все элементы имеют заданную длину, вы также можете сделать это:
any(second == search for _, second in data)
или для len (data [0]) == 4:
any(second == search for _, second, _, _ in data)
... и я бы рекомендовал использовать
for element in data:
...
вместо
for i in range(len(data)):
...
(для будущего использования, , если вы не хотите сохранить или использовать «i» , и просто чтобы вы знали '0' не требуется, вам нужно использовать полный синтаксис, только если вы начинаете при ненулевом значении)
>>> the_list =[ ['a','b'], ['a','c'], ['b''d'] ]
>>> any('c' == x[1] for x in the_list)
True
>>> my_list =[ ['a', 'b'], ['a', 'c'], ['b', 'd'] ]
>>> 'd' in (x[1] for x in my_list)
True
Редактирование для добавления:
Оба ответа Дэвида с использованием any и мой с использованием в закончатся, когда они найдут совпадение, поскольку мы используем генератор выражений. Вот тест с использованием бесконечного генератора, чтобы показать, что:
def mygen():
''' Infinite generator '''
while True:
yield 'xxx' # Just to include a non-match in the generator
yield 'd'
print 'd' in (x for x in mygen()) # True
print any('d' == x for x in mygen()) # True
# print 'q' in (x for x in mygen()) # Never ends if uncommented
# print any('q' == x for x in mygen()) # Never ends if uncommented
Мне просто нравится просто использовать в вместо == и any .
Нет ничего плохого в использовании генерального exp, но если цель состоит в том, чтобы встроить цикл ...
>>> import itertools, operator
>>> 'b' in itertools.imap(operator.itemgetter(1), the_list)
True
Также должен быть самым быстрым.
У Маркуса есть один способ избежать использования слова для
- вот другой, который должен иметь гораздо лучшую производительность в течение длительного времени the_list
s ... :
import itertools
found = any(itertools.ifilter(lambda x:x[1]=='b', the_list)
Вот питонический способ сделать это:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)
Или ... ну, я не собираюсь утверждать, что это «единственный истинный питонический способ», потому что в какой-то момент становится немного субъективным, что такое Pythonic, а что нет, или какой метод более Pythonic, чем другой. Но использование any ()
определенно более типично для Python, чем цикл for
, как, например, Ответ РичиХиндла ,
Конечно, в реализация any
, хотя она выходит из цикла, как только находит совпадение.
Так как мне было скучно, я сделал сценарий времени для сравнения производительности различных предложений, изменив некоторые из них по мере необходимости, чтобы API был таким же. Следует помнить, что самый быстрый - не всегда лучший, и быть быстрым - это определенно не то же самое, что быть Pythonic. При этом результаты ... странные. Очевидно, для
циклов очень быстрые, чего я не ожидал, поэтому я бы отнесся к ним с недоверием, не понимая, почему они вышли именно так.
В любом случае, когда Я использовал список, определенный в вопросе, с тремя подсписками по два элемента в каждом, от самого быстрого до самого медленного. Я получаю следующие результаты:
for
, тактовая частота 0,22 мкс для
цикла из исходного вопроса , но различия между ними должны дать некоторое представление о том, насколько близки разные методы.
Когда я использую более длинный список, все немного меняется. Я начал со списка в вопросе, с трех подсписок, и добавил еще 197 подсписок, в общей сложности 200 подсписок длины два. Используя этот более длинный список, вот результаты:
operator.itemgetter ()
, снова при 0,53 мкс ifilter ()
и Анонимный ответ , при 0,67 мкс any ()
, все приходящие на 0,81-0,82 мкс . Это те, которые сохраняют исходное время когда список расширяется. Остальные, которых нет, - это
for
цикл из исходного вопроса , при 1,24 мкс >>> the_list =[ ['a','b'], ['a','c'], ['b','d'] ]
>>> "b" in zip(*the_list)[1]
True
zip ()
берет кучу списков и группирует элементы вместе по индексу, эффективно транспонируя матрицу списков списков. Звездочка берет содержимое the_list
и отправляет его в zip
в качестве аргументов, поэтому вы фактически передаете три списка по отдельности, что и требуется для zip
. Осталось только проверить, есть ли «b»
(или что-то еще) в списке, состоящем из элементов с интересующим вас индексом.