python dict.update()가 개체를 반환하지 않는 이유는 무엇입니까?
다음 코드가 있습니다.
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
하지만 코드는 다소 번거롭게 느껴졌습니다.저는 다음과 같은 글을 쓸 수 있었으면 좋았을 것입니다.
def award(name, count, points, desc_string, my_size, parent):
if my_size > count:
return self.add_award({
"name": name,
"description": desc_string % count,
"points": points,
"parent_award": parent,
}.update(award_dict), siteAlias, alias).award
왜안그요래?요'래▁the▁whyt그▁doesn?update
법return
JQuery에서 작동하는 방식과 같이 체인을 허용하는 원본 사전?왜 파이썬에서는 허용되지 않습니까?
Python에서 두 개의 사전을 단일 식으로 병합하는 방법을 참조하십시오.회피책으로
Python은 대부분 실용적으로 구현된 명령 쿼리 분리: 돌연변이가 반환됩니다.None
가 있음)pop
;-) 그래서 그들은 접근자들과 혼동할 수 없습니다 (그리고 같은 맥락에서, 할당은 표현이 아닙니다, 진술-표현 분리가 거기에 있습니다 등).
그렇다고 해서 당신이 정말 원할 때 그것들을 병합할 수 있는 방법이 많지 않다는 것을 의미하지는 않습니다. 예를 들어,dict(a, **award_dict)
처럼 보이는 ..update
반환되었습니다. 만약 정말 중요하다고 생각한다면 그것을 사용하는 것이 어떻습니까?
편집: btw, 특정한 경우에는 생성할 필요가 없습니다.a
다음 중 하나를 수행합니다.
dict(name=name, description=desc % count, points=points, parent_award=parent,
**award_dict)
사용자와 정확히 동일한 의미를 가진 단일 딕트를 만듭니다.a.update(award_dict)
, (경우의항, 포함목충)의 award_dict
명시적으로 제공하는 것을 무시합니다. 다른 의미론, 즉 그러한 충돌을 "승리"하는 명시적인 항목을 가지려면 통과합니다.award_dict
유일한 위치 변수로서, 키워드 앞에, 그리고 뒤에.**
태형 --dict(award_dict, name=name
등).
Python의 API는 전통적으로 절차와 기능을 구분합니다.함수는 매개 변수(대상 개체 포함)에서 새 값을 계산합니다. 프로시저는 개체를 수정하고 아무것도 반환하지 않습니다(예: 없음을 반환함).그래서 절차에는 부작용이 있지만, 기능에는 영향이 없습니다.업데이트는 절차이므로 값을 반환하지 않습니다.
그렇게 하는 이유는 그렇지 않으면 바람직하지 않은 부작용이 생길 수 있기 때문입니다.고려하다
bar = foo.reverse()
역방향(목록 삽입을 반대로 함)도 목록을 반환하는 경우, 사용자는 역방향이 막대에 할당된 새 목록을 반환한다고 생각할 수 있으며, foo도 수정된다는 사실을 눈치채지 못할 수 있습니다.역귀환을 없음으로 설정하면 막대가 역귀환의 결과가 아님을 즉시 인식하고 역귀환의 효과가 무엇인지 더 자세히 볼 수 있습니다.
이는 다음과 같이 쉽습니다.
(lambda d: d.update(dict2) or d)(d1)
또는 사전을 수정하지 않는 것이 중요한 경우:
(lambda d: d.update(dict2) or d)(d1.copy())
상위 답변에 댓글을 달기에 충분한 평판이 없습니다.
@beardc 이것은 Cython 일이 아닌 것 같습니다.PyPy는 "TypeError: 키워드는 문자열이어야 함"을 제공합니다.
솔루션과 함께 제공하는 솔루션**kwargs
병합할 사전에는 문자열 유형의 키만 있기 때문에 작동합니다.
예.
>>> dict({1:2}, **{3:4})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings
대
>>> dict({1:2}, **{'3':4})
{1: 2, '3': 4}
>>> dict_merge = lambda a,b: a.update(b) or a
>>> dict_merge({'a':1, 'b':3},{'c':5})
{'a': 1, 'c': 5, 'b': 3}
병합된 딕트를 반환할 뿐만 아니라 첫 번째 매개 변수를 수정합니다.따라서 dict_merge(a,b)는 a를 수정합니다.
물론 모든 작업을 인라인으로 수행할 수도 있습니다.
>>> (lambda a,b: a.update(b) or a)({'a':1, 'b':3},{'c':5})
{'a': 1, 'c': 5, 'b': 3}
받아들일 수 없는 것이 아니라, 오히려.dicts
그런 식으로 구현되지 않았습니다.
장고의 ORM을 보면 체인을 광범위하게 활용하고 있습니다.낙담하지 않고, 당신은 심지어 상속받을 수 있습니다.dict
오버라이드만 가능합니다.update
업데이트를 수행return self
당신이 정말 원한다면요.
class myDict(dict):
def update(self, *args):
dict.update(self, *args)
return self
파티에 늦게 오는 사람들을 위해, 나는 어느 정도의 타이밍을 맞춰놓았습니다 (Py 3.7)..update()
기반 방법은 입력이 보존될 때는 약간(~5%) 빨라지고, 인플레이스 업데이트만 할 때는 눈에 띄게(~30%) 빨라집니다.
여느 때처럼 모든 벤치마크를 고려해야 합니다.
def join2(dict1, dict2, inplace=False):
result = dict1 if inplace else dict1.copy()
result.update(dict2)
return result
def join(*items):
iter_items = iter(items)
result = next(iter_items).copy()
for item in iter_items:
result.update(item)
return result
def update_or(dict1, dict2):
return dict1.update(dict2) or dict1
d1 = {i: str(i) for i in range(1000000)}
d2 = {str(i): i for i in range(1000000)}
%timeit join2(d1, d2)
# 258 ms ± 1.47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit join(d1, d2)
# 262 ms ± 2.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit dict(d1, **d2)
# 267 ms ± 2.74 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit {**d1, **d2}
# 267 ms ± 1.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
인플레이스 작업의 타이밍은 좀 더 까다롭기 때문에 추가 복사 작업을 통해 수정해야 합니다(첫 번째 타이밍은 참조용일 뿐입니다.
%timeit dd = d1.copy()
# 44.9 ms ± 495 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit dd = d1.copy(); join2(dd, d2)
# 296 ms ± 2.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit dd = d1.copy(); join2(dd, d2, True)
# 234 ms ± 1.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit dd = d1.copy(); update_or(dd, d2)
# 235 ms ± 1.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
import itertools
dict_merge = lambda *args: dict(itertools.chain(*[d.iteritems() for d in args]))
가능한 한 당신의 제안된 해결책에 가깝습니다.
from collections import ChainMap
return self.add_award(ChainMap(award_dict, {
"name" : name,
"description" : desc_string % count,
"points" : points,
"parent_award" : parent,
}), siteAlias, alias).award
방금 파이썬 3.4에서 직접 시도했습니다(그래서 그 공상을 사용할 수 없었습니다).{**dict_1, **dict_2}
구문)을 선택합니다.
저는 임의의 양의 사전을 제공할 뿐만 아니라 사전에 문자열이 아닌 키를 가질 수 있기를 원했습니다.
또한, 나는 새로운 사전을 만들고 싶어서 사용하지 않기로 결정했습니다.collections.ChainMap
(kinda 내가 사용하고 싶지 않은 이유.dict.update
초판에
제가 쓴 글은 다음과 같습니다.
def merge_dicts(*dicts):
all_keys = set(k for d in dicts for k in d.keys())
chain_map = ChainMap(*reversed(dicts))
return {k: chain_map[k] for k in all_keys}
merge_maps({'1': 1}, {'2': 2, '3': 3}, {'1': 4, '3': 5})
# {'1': 4, '3': 5, '2': 2}
항목 목록을 연결하여 병합:
d1 = {1: "one"}
d2 = {2: "two"}
dict(list(d1.items()) + list(d2.items()))
# {1: 'one', 2: 'two'}
언급URL : https://stackoverflow.com/questions/1452995/why-doesnt-a-python-dict-update-return-the-object
'sourcetip' 카테고리의 다른 글
C에서 "포장된" 구조는 무엇입니까? (0) | 2023.06.07 |
---|---|
Makefile:1: *** 구분 기호가 없습니다.이제 그만 (0) | 2023.06.07 |
Python을 사용하여 스프레드시트에 매크로 삽입 (0) | 2023.06.07 |
postback에서 postback의 원인이 되는 컨트롤을 Page_에서 확인하려면 어떻게 해야 합니까?Init 이벤트 (0) | 2023.06.07 |
유닉스 타임스탬프를 사용하여 MySQL에서 1분 주기로 그룹화하는 방법이 있습니까? (0) | 2023.06.07 |