Python определяет самый простой и понятный способ получить значение key2, если key1 отсутствует

#python #python-3.x #dictionary

#питон #python-3.x #словарь

Вопрос:

У меня есть python dict, подобный этому,

 d = {
"k1" : "v1",
"k2" : "v2"
}
 

Я хочу получить значение k1 из dict, что я могу сделать следующим образом,

 d.get("k1")
 

Но проблема в том, что иногда k1 будет отсутствовать в dict. В этом случае я хочу выбрать k2 из dict. Теперь я делаю это вот так

 val = d.get("k1", None)
if not val:
    val = d.get("k2", None)
 

Я тоже могу это сделать,

 if "k1" in d:
    val = d['k1']
else:
    val = d.get("k2", None)
 

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

Ответ №1:

None In d.get() указывает, что делать, если ничего не найдено.

Просто добавьте другое d.get() вместо None .

 d.get('k1', d.get('k2', None))
#'v1'
 

Комментарии:

1. Мне понравилась идея вложенности get. Но это может стать довольно сложным, если я хочу выполнить поиск по 20 или около того ключам.

Ответ №2:

A d.get внутри a d.get :

Может быть, попробуйте двойной dict.get :

 val = d.get("k1", d.get("k2", None))
 

И теперь:

 print(val)
 

Даст k1 значение ‘s, если есть a k1 , и k2 значение ‘s, если нет имени ключа k1 , но если также нет a k2 , оно дает None .

Мой код выполняет a d.get , но внутри параметров второй аргумент, который вы сделали None , в этом случае мы делаем другой d.get , который является for k2 , а во втором d.get он, наконец, имеет второй аргумент as None , он выдает только None в том случае, если оба ключа не d включены.

Редактировать:

Если есть больше ключей (т. Е. k3 k4 …), Просто добавьте больше d.get ключей:

 val = d.get("k1", d.get("k2", d.get("k3", d.get("k4"))))
 

И просто добавьте:

 print(val)
 

Для его вывода.

Использование генератора с next :

Вы также можете использовать генератор с next , чтобы получить первое значение, например:

 val = next((d[i] for i in ['k1', 'k2', 'k3', 'k4'...] if i in d), None)
 

И теперь:

 print(val)
 

Также даст правильный результат.

Не забудьте добавить a None , чтобы, если в любом из этих ключей нет никаких значений, он не выдавал a StopIteration .

Комментарии:

1. Этот мне понравился. Это будет довольно сложно, если у меня есть 10 или 20 ключей, которые я хочу найти. Я искал что-то вроде d.get(["k1", "k2", "k3"], None) — Где он будет искать k1, если не найден, ищите k2 и так далее.

2. Просто вопрос об эффективности — однострочник будет искать все четыре ключа, даже если присутствует первый.

3. @SreeramTP Да, к сожалению, для словарей такого понятия не существует 🙁

4. Я думаю, что мне нужно итеративно искать все ключи

5. @SreeramTP Я поступил по-другому 😉

Ответ №3:

Если нет встроенной функции, которая делает то, что вы хотите, тогда вы можете написать свою собственную; вам нужно написать ее только один раз, а затем везде, где вы ее используете, она будет однострочной.

 def get_alt(d, *keys, default=None):
    return next((d[k] for k in keys if k in d), default)
 

Примеры:

 >>> my_dict = {'a': 1, 'b': 2, 'c': 3}
>>> get_alt(my_dict, 'a', 'b', 'c')
1
>>> get_alt(my_dict, 'd', 'b', 'c')
2
>>> get_alt(my_dict, 'd', 'e', 'c')
3
>>> get_alt(my_dict, 'd', 'e', 'f') is None
True
>>> get_alt(my_dict, 'd', 'e', 'f', default=4)
4
 

Комментарии:

1. О, то же, что и мой второй способ 1 🙂

Ответ №4:

 val = d.get("k1") or d.get("k2")
 

Это эквивалентно вашему решению «я делаю это так сейчас». None значение по get умолчанию, указывать его не нужно. И в отличие от вложенных get s, размещенных другими, это не выполняет оба get s, если первый выполняется успешно.