programing

조건이 충족되는 경우에만 딕트에 추가

closeapi 2023. 7. 30. 17:49
반응형

조건이 충족되는 경우에만 딕트에 추가

사용 중urllib.urlencode웹 POST 매개 변수를 구축하기 위해 몇 가지 값을 추가합니다.None그들을 위해 존재합니다.

apple = 'green'
orange = 'orange'
params = urllib.urlencode({
    'apple': apple,
    'orange': orange
})

그것은 잘 작동하지만, 만약 내가 만든다면.orange변수 선택 사항입니다. 매개 변수에 추가되지 않도록 하려면 어떻게 해야 합니까?다음과 같은 것(의사 코드):

apple = 'green'
orange = None
params = urllib.urlencode({
    'apple': apple,
    if orange: 'orange': orange
})

이것이 충분히 명확했으면 좋겠는데, 이것을 해결하는 방법을 아는 사람이 있나요?

이니셜을 생성한 후 키를 별도로 추가해야 합니다.dict:

params = {'apple': apple}
if orange is not None:
    params['orange'] = orange
params = urllib.urlencode(params)

Python에는 키를 조건부로 정의하는 구문이 없습니다. 이미 시퀀스에 모든 것이 있는 경우 딕트 이해를 사용할 수 있습니다.

params = urllib.urlencode({k: v for k, v in (('orange', orange), ('apple', apple)) if v is not None})

하지만 그것은 그다지 읽을 수 없습니다.

Python 3.9 이상을 사용하는 경우 새로운 dict 병합 연산자 지원 및 조건식을 사용할 수 있습니다.

params = urllib.urlencode(
    {'apple': apple} | 
    ({'orange': orange} if orange is not None else {})
)

하지만 가독성에 문제가 있다는 것을 알게 되었고, 그래서 아마도 여전히 별도로 사용할 것입니다.if식:

params = {'apple': apple}
if orange is not None:
    params |= {'orange': orange}
params = urllib.urlencode(params)

또 다른 옵션은 사전 압축 풀기를 사용하는 것이지만, 단일 키의 경우에는 더 읽기 쉬운 것이 아닙니다.

params = urllib.urlencode({
    'apple': apple,
    **({'orange': orange} if orange is not None else {})
})

저는 개인적으로 이것을 절대 사용하지 않을 것입니다, 그것은 너무 구식이고 별도의 것을 사용하는 것만큼 명확하고 명확하지 않습니다.if진술.파이썬의 선지자가 말한 것은 다음과 같습니다.가독성이 중요합니다.

squrept의 대답을 참고로, 여기 하위 클래스가 있습니다.dict원하는 대로 동작하는 경우:

class DictNoNone(dict):
    def __setitem__(self, key, value):
        if key in self or value is not None:
            dict.__setitem__(self, key, value)


d = DictNoNone()
d["foo"] = None
assert "foo" not in d

이렇게 하면 기존 키의 값을 다음으로 변경할 수 있습니다.None하지만 할당하는 것None존재하지 않는 키는 no-op입니다.항목을 다음으로 설정하려면None사전에 이미 있는 경우 사전에서 제거하려면 다음을 수행합니다.

def __setitem__(self, key, value):
    if value is None:
        if key in self:
            del self[key]
    else:
        dict.__setitem__(self, key, value)

의 값None 공사 중에 그것들을 건네주면 들어갈 수 있습니다.이 문제를 방지하려면 다음을 추가합니다.__init__필터링 방법:

def __init__(self, iterable=(), **kwargs):
    for k, v in iterable:
        if v is not None: self[k] = v
    for k, v in kwargs.iteritems():
        if v is not None: self[k] = v

사전을 만들 때 원하는 조건으로 전달할 수 있도록 작성하여 일반화할 수도 있습니다.

class DictConditional(dict):
    def __init__(self, cond=lambda x: x is not None):
        self.cond = cond
    def __setitem__(self, key, value):
        if key in self or self.cond(value):
            dict.__setitem__(self, key, value)

d = DictConditional(lambda x: x != 0)
d["foo"] = 0   # should not create key
assert "foo" not in d

꽤 오래된 질문이지만 빈 딕트로 딕트를 업데이트하는 것은 아무 것도 하지 않는다는 사실을 사용하는 대안이 있습니다.

def urlencode_func(apple, orange=None):
    kwargs = locals().items()
    params = dict()
    for key, value in kwargs:
        params.update({} if value is None else {key: value})
    return urllib.urlencode(params)

제가 제안하는 한 가지 기술은 사전 압축 풀기 연산자를 사용하는 것입니다.

apple = 'green'
orange = None
params = urllib.urlencode({
    'apple': apple,
    **({ 'orange': orange } if orange else {})
})

설명.

기본적으로, 만약에.orange이라None그러면 위의 사전은 다음과 같이 단순화됩니다.

{
    'apple': apple,
    **({})
}

# which results in just
{
    'apple': apple,
} 

반대는 다음과 같습니다.orange아닙니다None:

{
    'apple': apple,
    **({ "orange": orange })
}

# which results in just
{
    'apple': apple,
    'orange': orange
} 

가독성은 인라인에서 키를 조건부로 추가하는 경우의 단점입니다.가독성 문제를 해결하는 데 도움이 되는 기능을 만들 수 있습니다.

from typing import Callable

def cond_pairs(
        cond: bool, pairs: Callable[[], dict],
) -> dict:
    return pairs() if cond else {}

{
    'apple': apple,
    **cond_pairs(orange, lambda: { 'orange': orange })
}

나는 이 일을 했다.도움이 되길 바랍니다.

apple = 23
orange = 10
a = {
    'apple' : apple,
    'orange' if orange else None : orange
}

출력: 예상출력:{'orange': 10, 'apple': 23}

하만지라면, 만에약.orange = None그러면 단일 항목이 있을 것입니다.None:None를 들어 다음과 같이 .

apple = 23
orange = None
a = {
    'apple' : apple,
    'orange' if orange else None : orange
}

출력: 예상출력:{None: None, 'apple': 23}

할당 후 없음을 선택 취소할 수 있습니다.

apple = 'green'
orange = None
dictparams = {
    'apple': apple,
    'orange': orange
}
for k in dictparams.keys():
    if not dictparams[k]:
        del dictparams[k]
params = urllib.urlencode(dictparams)

다른 유효한 대답은 없음 값을 저장하지 않는 자체 딕트와 같은 컨테이너를 만들 수 있다는 것입니다.

class MyDict:
    def __init__(self):
        self.container = {}
    def __getitem__(self, key):
        return self.container[key]
    def __setitem__(self, key, value):
        if value != None:
            self.container[key] = value
    def __repr__(self):
        return self.container.__repr__()

a = MyDict()
a['orange'] = 'orange';
a['lemon'] = None

print a

산출량:

{'orange': 'orange'}

저는 여기 답변에 있는 깔끔한 속임수가 정말 마음에 듭니다: https://stackoverflow.com/a/50311983/3124256 .

하지만 몇 가지 함정이 있습니다.

  1. if값을 기호) (키와 값을 나타내는 기호)
  2. 페키스None: None으로 "▁in기▁the▁entry의"에 입력합니다.dict

이 문제를 방지하려면 다음을 수행할 수 있습니다.

apple = 23
orange = None
banana = None
a = {
    'apple' if apple else None: apple,
    'orange' if orange else None : orange,
    'banana' if banana else None: banana,
    None: None,
}
del a[None]

출력: 예상출력:{'apple': 23}

고: 더None: None엔트리는 다음 두 가지를 보장합니다.

  1. None합니다.del오류가 발생하지 않음)
  2. values'의딕트에 .del이후)

이런 것들이 걱정이 안된다면 생략하고 델을 포장하면 됩니다.try...except( (으)로 None가 가앞에있다 앞에 .del 하기 위해 (에) 값에. 또는 2번 주소를 지정하기 위해 (키 이외에) 값에 조건부 검사를 적용할 수도 있습니다.

는 발전기 기능을 사용하는 것이 이해하기 쉽고 충분히 유연하다고 생각합니다.또한 Python 2와 3 모두에서 작동합니다.

def generate_request_items(apple, orange):
    yield "apple", apple
    if orange:
        yield "orange", orange
    # Add additional conditionals and yield statements here


apple = 'green'
orange = None
params = urllib.urlencode(dict(generate_request_items(apple, orange)))

사전 이해를 사용하여 단일 조건을 사용하여 모든 선택 항목을 처리할 수 있습니다.

apple = "red"
orange = None
dictparams = {
    key: value for key, value in
    {
        "apple": apple,
        "orange": orange
    }.items()
    if value is not None
}

dictparams에 결에포지않음이 ."orange" 이경우, 왜하면 때문에.orange이라None:

{'apple': 'red'}

데이터를 추가한 다음 나중에 다음 조건을 통해 필터링할 수 있습니다.

data = {
    "foo": None,
    "bar": "1234",
    "baz": None,
}
data = {k: v for k, v in data.items() if v is not None}

결과:

data = {
    "bar": "1234",
}

자한내답이질문참조/에 대한 이 하십시오.filter/lambda사전의 기능:

임의의 조건 함수에 따라 사전을 필터링하는 방법은 무엇입니까?

fruits = [("apple", get_apple()), ("orange", get_orange()), ...]

params = urllib.urlencode({ fruit: val for fruit, val in fruits if val is not None })

제외하고 싶은 다른 프로프 이름을 다시 사용하는 반직관적이지만 신뢰할 수 있는 해킹이 있습니다.

{
    'orange' if orange else 'apple': orange,
    'apple': apple,
}

이 경우 후자의 'apple'이 이전의 'apple'보다 우선하여 효과적으로 제거됩니다.조건식은 실제 식을 초과해야 합니다.

친절한 모든 사람들의 답을 만드는 것, 나는 이것을 단지 그것이 아니라 걸러내기 위해 사용하지 않습니다.NoneFalse.로 값,즉 False로 평가되는 입니다.에 맞는 것입니다.빈 않기 때문입니다. 저는 빈 것을 원하지 않기 때문입니다.False또는None.

class DictNoNone(dict):

    def __init__(self, iterable=(), **kwargs):
        for k, v in iterable:
            if v: self[k] = v
        for k, v in kwargs.items():
            if v: self[k] = v

    def __setitem__(self, key, value):
        if not value:
            if key in self:
                del self[key]
        else:
            dict.__setitem__(self, key, value)

언급URL : https://stackoverflow.com/questions/14263872/only-add-to-a-dict-if-a-condition-is-met

반응형