Использование в операторе для сопоставления элементов в кортеже - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь понять, почему оператор in ниже также не совпадает и печатает (4, 'foobar') и ('foobar', 5) (это соответствует остальным). Пытаюсь закрепить мое понимание с помощью кортежей. Я пытался сопоставить все кортежи, в которых есть «foo», «bar» или «foobar» в любой части кортежа.

ls = [(1, 'foo'), ('bar2'), ('foo', 'bar', 3), (4, 'foobar'), ('foobar', 5), ('foobar')]
print [x for x in ls if 'foo' in x or 'bar' in x]
[(1, 'foo'), 'bar2', ('foo', 'bar', 3), 'foobar']

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Для кортежа 'foo' in x означает "есть ли элемент x, который равен 'foo'", а не "есть ли элемент x, который содержит 'foo' ".

Чтобы сделать последнее, вы можете сделать что-то вроде

any('foo' in y for y in x)

Однако для строки 'foo' in x означает «является 'foo' подстрокой x».

Кроме того, один элемент в скобках (например, ('bar2') и ('foobar')) не составляет кортеж. Для создания кортежа вам обычно нужна запятая в скобках: ('bar2',) и ('foobar',). Оба эти элемента совпадают, поскольку они не являются кортежами и содержат правильную подстроку.

Если вы ищете специально foo, bar и foobar, а не что-то вроде barfoo, просто добавьте дополнительный or к пониманию:

[x for x in ls if 'foo' in x or 'bar' in x or 'foobar' in x]

Вы можете обобщить, используя any, выполнив что-то вроде

search_terms = ('foo', 'bar', 'foobar')
[x for x in ls if any(a in x for a in search_terms)]
0 голосов
/ 29 августа 2018

Потому что ('bar2') не кортеж, а просто строка 'bar2' (а 'bar' в этой строке), в то время как ('foobar', 1) является кортежем, а 'bar' не один из ('foobar', 1).

'in' работает по-разному для списка / кортежа и для одной строки. Применительно к строке она спрашивает "является ли 'foo' подстрокой?". Когда применяется к списку / кортежу, он спрашивает "равно ли 'foo' одному из элементов списка / кортежа?".

...