Python, если ЛЮБОЙ из элементов в массиве существует в объекте - PullRequest
0 голосов
/ 30 октября 2018

Я хочу проверить, существует ли ЛЮБОЙ из элементов в массиве в данном объекте.

Вот мой текущий код, который работает:

if "Mod" in [role.name for role in data.roles]:

но если я сделаю это ...

roles = ["Mod", "Admin"]

if any(roles) in [role.name for role in data.roles]:

Это не работает.

Как мне этого добиться? Любая помощь будет оценена

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Do:

roles = ["Mod", "Admin"]
if any(role in [role.name for role in data.roles] for role in roles):
    do something

Что он делает? Прежде всего, у нас есть «список имен ролей», составленный с выражением [role.name for role in data.roles]. Давайте назовем это data_role_names. Теперь оно уменьшается до:

roles = ["Mod", "Admin"]
if any(role in data_role_names for role in roles):
    do something

Тогда немного теории об итерациях. Это мои любимые посты об этом: Введение в генераторы Python и Итерации и итераторы и генераторы . any() ожидает повторяемость. Генератор - это «[..] особый вид итератора », итеративный.

Генератор сделан выражением в скобках. Просто попробуйте:

a = (role in data_role_names for role in roles)

print(type(a))

И это печатает:

Python 3.6.1 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux

<class 'generator'>

Любой () будет:

Возвращает True, если какой-либо элемент итерируемого равен true. Если итерация пусто, вернуть False

Это означает, что для каждого role, указанного в roles (в вашем примере roles = ["Mod", "Admin"]), и возвращается true, если какой-либо из них принадлежит data_role_names.

0 голосов
/ 30 октября 2018

Вы также можете использовать & вместо

find = 'Mod'
roles = ["Mod", "Admin"]

if set(roles) & {find}: # {} converts 'Mod' to set
    print("match")

# output
# match
0 голосов
/ 30 октября 2018

Использовать установленное пересечение, как в следующем игрушечном примере :

roles = ["Mod", "Admin"]

if set(roles).intersection(["Mod"]):
        print("match")

выход

match

В вашем примере это будет примерно так:

if set(roles).intersection([role.name for role in data.roles]):
        do something

Или, если вы предпочитаете:

roles = ["Mod", "Admin"]
data_roles = set(role.name for role in data.roles)

if any(role in data_roles for role in roles):
        do something
...