#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, если первый выполняется успешно.