#python #dictionary
Вопрос:
Если я сделаю что-то подобное
some_obj = {"a": 1, "b": 2, "c": 3}
first, *rest = some_obj
Я получу список, но я хочу, чтобы он был в 2 словарях: first = {"a": 1}
и rest = {"b": 2, "c": 3}
. Как я понимаю, я могу создать функцию, но мне интересно, смогу ли я сделать это в одной строке, как в javascript с оператором распространения.
Ответ №1:
Я не знаю, есть ли надежный способ добиться этого в одной строке, но вот один метод.
Сначала распакуйте key
s и values
( .items()
). Используя some_obj
только итерацию по клавишам.
>>>>>> some_obj = {"a":1, "b":2, "c": 3} >>>>>> во-первых, *rest = some_obj.>>>элементы()
Но это вернет кортеж,
>>> first
('a', 1)
>>> rest
[('b', 2), ('c', 3)]
Но вы можете снова преобразовать обратно в dict одним dict
звонком.
>>> dict([first])
{'a': 1}
>>> dict(rest)
{'b': 2, 'c': 3}
Комментарии:
1. Я думаю, что это самое лучшее, что может быть. Python
dict
s гарантировал порядок вставки с 3.7, но для этого не так много поддержки методов, как для итераций. Например, вы можете выполнять итерации в порядке вставки, но нет индексации или нарезки. Одна странная вещь заключаетсяOrderedDict
в том, что после 3.7 это казалось излишним, но онOrderedDict.popitem
может удалить первый или последний элемент, аdict.popitem
не может.
Ответ №2:
Один лайнер, вдохновленный Абдулом Ниясом P M’s:
first, rest = dict([next(i := iter(some_obj.items()))]), dict(i)
Использует выражение присваивания, введенное в Python 3.8 почти два года назад.
Ответ №3:
k = next(iter(some_obj)) # get the first key
first = {k: some_obj.pop(k)}
rest = some_obj
Если вам нужно сохранить исходный объект нетронутым — обратите внимание, что это ухудшается с O(1) до O(n) как во времени, так и в пространстве:
k = next(iter(some_obj))
rest = some_obj.copy()
first = {k: rest.pop(k)}
Ответ №4:
Ответ @AbdulNiyasPM совершенно прекрасен, но поскольку вы попросили однострочный, вот один из способов сделать это (хотя сначала вам придется это сделать from operator import itemgetter
):
first, rest = map(dict, itemgetter(slice(0, 1), slice(1, None))(list(some_obj.items())))
Если вы предпочитаете ничего не импортировать, вы можете использовать аналогичную однострочную функцию с lambda
функцией, которая принимает один фиксированный аргумент, а остальные в качестве аргументов переменной длины:
first, rest = map(dict, (lambda f, *r: ((f,), r))(*some_obj.items()))
Демо: https://replit.com/@blhsing/ImpeccableEllipticalGeeklog
Комментарии:
1. Извините, пришлось понизить голос — это очень грубо, и вопрос, заданный для «простого варианта» 🙂 Просто потому, что кто-то просит однострочный, не означает, что мы должны потакать ему..