Подтвердить что ты не робот

Как проверить, входит ли один из следующих элементов в список?

Я пытаюсь найти короткий путь, чтобы увидеть, есть ли какой-либо из следующих элементов в списке, но моя первая попытка не работает. Помимо написания функции для достижения этой цели, это короткий способ проверить, находится ли один из нескольких элементов в списке.

>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True
4b9b3361

Ответ 1

>>> L1 = [2,3,4]
>>> L2 = [1,2]
>>> [i for i in L1 if i in L2]
[2]


>>> S1 = set(L1)
>>> S2 = set(L2)
>>> S1.intersection(S2)
set([2])

Оба пустых списка и пустые наборы являются False, поэтому вы можете использовать значение непосредственно как значение истины.

Ответ 2

А, Тобиас, ты избил меня. Я думал об этом небольшом изменении вашего решения:

>>> a = [1,2,3,4]
>>> b = [2,7]
>>> print(any(x in a for x in b))
True

Ответ 3

Возможно немного более ленивый:

a = [1,2,3,4]
b = [2,7]

print any((True for x in a if x in b))

Ответ 4

Подумайте, что на самом деле говорит код!

>>> (1 or 2)
1
>>> (2 or 1)
2

Это должно объяснить это.:) Python, по-видимому, реализует "ленивый", который не должен удивлять. Он выполняет это примерно так:

def or(x, y):
    if x: return x
    if y: return y
    return False

В первом примере x == 1 и y == 2. Во втором примере это наоборот. Поэтому он возвращает разные значения в зависимости от их порядка.

Ответ 5

a = {2,3,4}
if {1,2} & a:
    pass

Код версии для гольфа. Рассмотрите возможность использования набора, если имеет смысл это сделать. Я считаю это более читаемым, чем понимание списка.

Ответ 6

1 строка без учета списка.

>>> any(map(lambda each: each in [2,3,4], [1,2]))
True
>>> any(map(lambda each: each in [2,3,4], [1,5]))
False
>>> any(map(lambda each: each in [2,3,4], [2,4]))
True

Ответ 7

Лучше всего я мог бы придумать:

any([True for e in (1, 2) if e in a])

Ответ 8

Когда вы думаете, что "проверьте, есть ли a в b", подумайте о хэшах (в данном случае, устанавливает). Самый быстрый способ - хешировать список, который вы хотите проверить, а затем проверить каждый элемент там.

Вот почему ответ Джо Коберг быстрый: проверка пересечения множеств происходит очень быстро.

Если у вас нет большого количества данных, создание наборов может быть пустой тратой времени. Таким образом, вы можете создать список и просто проверить каждый элемент:

tocheck = [1,2] # items to check
a = [2,3,4] # the list

a = set(a) # convert to set (O(len(a)))
print [i for i in tocheck if i in a] # check items (O(len(tocheck)))

Когда количество элементов, которые вы хотите проверить, невелико, разница может быть незначительной. Но проверьте количество чисел против большого списка...

Тесты:

from timeit import timeit

methods = ['''tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',

'''L1 = [2,3,4]
L2 = [1,2]
[i for i in L1 if i in L2]''',

'''S1 = set([2,3,4])
S2 = set([1,2])
S1.intersection(S2)''',

'''a = [1,2]
b = [2,3,4]
any(x in a for x in b)''']

for method in methods:
    print timeit(method, number=10000)

print

methods = ['''tocheck = range(200,300) # items to check
a = range(2, 10000) # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',

'''L1 = range(2, 10000)
L2 = range(200,300)
[i for i in L1 if i in L2]''',

'''S1 = set(range(2, 10000))
S2 = set(range(200,300))
S1.intersection(S2)''',

'''a = range(200,300)
b = range(2, 10000)
any(x in a for x in b)''']

for method in methods:
    print timeit(method, number=1000)

скорости:

M1: 0.0170331001282 # make one set
M2: 0.0164539813995 # list comprehension
M3: 0.0286040306091 # set intersection
M4: 0.0305438041687 # any

M1: 0.49850320816 # make one set
M2: 25.2735087872 # list comprehension
M3: 0.466138124466 # set intersection
M4: 0.668627977371 # any

Метод, который является последовательно быстрым, состоит в том, чтобы сделать один набор (списка), но пересечение работает на больших наборах данных наилучшим образом!

Ответ 9

В Python 3 мы можем начать использовать распакованную звездочку. Дано два списка:

any({*a} & {*b})

Ответ 10

В некоторых случаях (например, уникальные элементы списка) можно использовать операции набора.

>>> a=[2,3,4]
>>> set(a) - set([2,3]) != set(a)
True
>>> 

Или, используя set.isdisjoint(),

>>> not set(a).isdisjoint(set([2,3]))
True
>>> not set(a).isdisjoint(set([5,6]))
False
>>> 

Ответ 11

Это будет сделано в одной строке.

>>> a=[2,3,4]
>>> b=[1,2]
>>> bool(sum(map(lambda x: x in b, a)))
True

Ответ 12

Я собрал несколько решений, упомянутых в других ответах и комментариях, а затем провел тест скорости. not set(a).isdisjoint(b) оказался самым быстрым, он также не сильно замедлился, когда результат был False.

Каждый из трех прогонов тестирует небольшой образец возможных конфигураций a и b. Время в микросекундах.

Any with generator and max
        2.093 1.997 7.879
Any with generator
        0.907 0.692 2.337
Any with list
        1.294 1.452 2.137
True in list
        1.219 1.348 2.148
Set with &
        1.364 1.749 1.412
Set intersection explcit set(b)
        1.424 1.787 1.517
Set intersection implicit set(b)
        0.964 1.298 0.976
Set isdisjoint explicit set(b)
        1.062 1.094 1.241
Set isdisjoint implicit set(b)
        0.622 0.621 0.753

import timeit

def printtimes(t):
    print '{:.3f}'.format(t/10.0),

setup1 = 'a = range(10); b = range(9,15)'
setup2 = 'a = range(10); b = range(10)'
setup3 = 'a = range(10); b = range(10,20)'

print 'Any with generator and max\n\t',
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(x in max(a,b,key=len) for x in min(b,a,key=len))',setup=setup3).timeit(10000000))
print

print 'Any with generator\n\t',
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any(i in a for i in b)',setup=setup3).timeit(10000000))
print

print 'Any with list\n\t',
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('any([i in a for i in b])',setup=setup3).timeit(10000000))
print

print 'True in list\n\t',
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('True in [i in a for i in b]',setup=setup3).timeit(10000000))
print

print 'Set with &\n\t',
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a) & set(b))',setup=setup3).timeit(10000000))
print

print 'Set intersection explcit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(set(b)))',setup=setup3).timeit(10000000))
print

print 'Set intersection implicit set(b)\n\t',
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('bool(set(a).intersection(b))',setup=setup3).timeit(10000000))
print

print 'Set isdisjoint explicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup2).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(set(b))',setup=setup3).timeit(10000000))
print

print 'Set isdisjoint implicit set(b)\n\t',
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup1).timeit(10000000))
printtimes(timeit.Timer('not set(a).isdisjoint(b)',setup=setup3).timeit(10000000))
print

Ответ 13

Я должен сказать, что моя ситуация может быть не той, что вы ищете, но она может предоставить альтернативу вашему мышлению.

Я пробовал оба метода set() и any(), но все еще есть проблемы со скоростью. Итак, я вспомнил, что Рэймонд Хеттингер сказал, что все в python - это словарь и используй dict, когда можешь. Так вот что я попробовал.

Я использовал defaultdict с int для обозначения отрицательных результатов и использовал элемент в первом списке в качестве ключа для второго списка (преобразованного в defaultdict). Поскольку у вас есть мгновенный поиск с помощью dict, вы сразу же знаете, существует ли этот элемент в defaultdict. Я знаю, что вы не всегда можете изменить структуру данных для вашего второго списка, но если вы можете с самого начала, то это намного быстрее. Возможно, вам придется преобразовать list2 (больший список) в defaultdict, где ключ - это потенциальное значение, которое вы хотите проверить из небольшого списка, а значение равно 1 (попадание) или 0 (без попадания, по умолчанию).

from collections import defaultdict
already_indexed = defaultdict(int)

def check_exist(small_list, default_list):
    for item in small_list:
        if default_list[item] == 1:
            return True
    return False

if check_exist(small_list, already_indexed):
    continue
else:
    for x in small_list:
        already_indexed[x] = 1

Ответ 14

print (1 in a) or (2 in a)

print (2 in a) or (5 in a)

Это очень старый вопрос, но я не был доволен ни одним из ответов, поэтому мне пришлось добавить это ради потомства.

Ответ 15

Simple.

_new_list = []
for item in a:
    if item in b:
        _new_list.append(item)
    else:
        pass