Я пытаюсь сделать:
award_dict = {
"url" : "http://facebook.com",
"imageurl" : "http://farm4.static.flickr.com/3431/3939267074_feb9eb19b1_o.png",
"count" : 1,
}
def award(name, count, points, desc_string, my_size, parent) :
if my_size > count :
a = {
"name" : name,
"description" : desc_string % count,
"points" : points,
"parent_award" : parent,
}
a.update(award_dict)
return self.add_award(a, siteAlias, alias).award
Но если бы я чувствовал себя действительно громоздким в функции, и я бы лучше сделал:
return self.add_award({
"name" : name,
"description" : desc_string % count,
"points" : points,
"parent_award" : parent,
}.update(award_dict), siteAlias, alias).award
Почему обновление не возвращает объект, чтобы вы могли связать?
JQuery делает это для создания цепочки. Почему это не приемлемо в питоне?
python
dictionary
language-design
language-features
Пол Тарьян
источник
источник
newdict = dict(dict001, **dict002)
Ответы:
Python в основном реализует прагматически окрашенный вид разделения команд и запросов : мутаторы возвращаются
None
(с прагматически вызванными исключениями, такими какpop
;-), поэтому их нельзя спутать со средствами доступа (и в том же духе, присваивание не является выражением, оператором -выражение разделения есть и т. д.).Это не означает, что не так много способов объединить вещи, когда вы действительно хотите, например,
dict(a, **award_dict)
создать новый диктат, очень похожий на тот, который вы, кажется, хотите.update
вернуть, - так почему бы не использовать TH, если вы действительно чувствуете, что это важно ?Изменить : кстати, нет необходимости, в вашем конкретном случае, чтобы создать
a
по пути, либо:создает единый запрос с точно такой же семантикой, что и у вас
a.update(award_dict)
(включая, в случае конфликтов, тот факт, что записи вaward_dict
файле переопределяют те, которые вы даете явно; чтобы получить другую семантику, т. е. иметь явные записи, «выигрывая» в таких конфликтах, передатьaward_dict
в качестве единственного позиционного аргумента, перед ключевыми и лишить**
формы - иdict(award_dict, name=name
т. д. и т. д.).источник
a
вообще, между прочим,TypeError
dict(old_dict, old_key=new_value)
не будет бросать несколько значений для ключевого слова и возвращать новый dict.API Python, по соглашению, различает процедуры и функции. Функции вычисляют новые значения из их параметров (включая любой целевой объект); процедуры изменяют объекты и ничего не возвращают (т.е. они возвращают None). Таким образом, процедуры имеют побочные эффекты, а функции - нет. Обновление - это процедура, следовательно, она не возвращает значение.
Мотивация для этого заключается в том, что в противном случае вы можете получить нежелательные побочные эффекты. Рассматривать
Если реверс (который переворачивает список на месте) также вернет список, пользователи могут подумать, что реверс возвращает новый список, который присваивается bar, и никогда не заметят, что foo также модифицируется. Делая обратный возврат None, они сразу распознают, что гистограмма не является результатом разворота, и будут смотреть ближе, каков эффект разворота.
источник
reverse(foo)
чувствует себя странно.bar=foo[:]
), а затем восстановите копию.bar = foo.reverse()
, вы могли бы подумать, чтоfoo
это не изменено. Чтобы избежать путаницы, у вас есть и то,foo.reverse()
и другоеbar = reversed(foo)
.Это легко как:
источник
Обратите внимание, что, кроме того, что он возвращает объединенный dict, он изменяет первый параметр на месте. Таким образом, dict_merge (a, b) изменит a.
Или, конечно, вы можете сделать все это встроенным:
источник
lambda
не следует использовать , как , что, вместо того, чтобы использовать обычную функциюdef
вместоa.update(b) or a
недостаточно репутации для комментария, оставленного сверху ответа
@beardc, похоже, это не CPython. PyPy дает мне «TypeError: ключевые слова должны быть строками»
Решение
**kwargs
работает только потому, что объединяемый словарь имеет только ключи типа string .т.е.
против
источник
Дело не в том, что это неприемлемо, а в том, что это
dicts
не было реализовано таким образом.Если вы посмотрите на ORM Джанго, он широко использует цепочку. Это не препятствует, вы можете даже наследовать
dict
и только переопределять,update
чтобы сделать обновление иreturn self
, если вы действительно этого хотите.источник
как можно ближе к вашему предложенному решению
источник
Для тех, кто опаздывает на вечеринку, я собрал время (Py 3.7), показывая, что
.update()
основанные методы выглядят немного (~ 5%) быстрее, когда входные данные сохраняются, и заметно (~ 30%) быстрее, когда просто обновляются на месте ,Как обычно, все критерии должны быть взяты с крошкой соли.
Временные интервалы для операций на месте немного сложнее, поэтому их необходимо будет модифицировать вместе с дополнительной операцией копирования (первый тайминг только для справки):
источник
источник
Просто пробовал это сам в Python 3.4 (поэтому не смог использовать причудливый
{**dict_1, **dict_2}
синтаксис).Я хотел иметь возможность иметь нестроковые ключи в словарях, а также предоставлять произвольное количество словарей.
Кроме того, я хотел создать новый словарь, поэтому я решил не использовать
collections.ChainMap
(по той причине, что я не хотел использоватьdict.update
изначально.Вот что я в итоге написал:
источник