2016-10-20 4 views
2

문자열로 구성 또는 사전 필터 파이썬 사전 나는 사전을 가지고

parameters = { 
"date": {'date':"2015-12-13"}, 
"name": "Nick", 
"product": "BT Adapter", 
"transaction-id": "" 
} 

그리고 내가 ['2015-12-13', 'BT Adapter', 'Nick'] 같은 목록을 얻을 필요가 값. 그것이에는 사전이없는 경우

print filter(lambda x: x if len(x) > 0 and type(x) is not dict else None, parameters.values()) 완벽하게 작동하지만,에 사전에 내가

print filter(lambda x: x if len(x) > 0 and type(x) is not dict else map(lambda y: x[y], x.keys()), parameters.values()) 

과 가치의 추출을 시도하고 난 AttributeError: 'str' object has no attribute 'keys'를 얻을. 모든 값을 추출하는 방법은 무엇입니까?

+3

'렌 (X)> 0 '이다 빈 문자열의 경우'False '이므로'else' 부분이 실행되고'str'은'keys' 메소드가 없습니다. –

+0

제쳐두고'type (x) is not dict'보다는'is isinstance (x, dict) '를 사용하는 것이 더 관용적입니다. 의미는 약간 다르지만, 당신이 원하는 것에 더 가깝다고 생각합니다. –

+0

사전을 입력으로 얻으려는 출력을 제공하면 정말 도움이 될 것입니다 ... 사전 값이나 빈 문자열을 어떻게 처리 할 것인지 명확하지 않습니다 ... BTW :'map (lambda – Bakuriu

답변

1
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 


def magic(params): 
    dicts = [params] 
    values = [] 

    while len(dicts): 
     d = dicts.pop() 

     for value in d.values(): 
      if isinstance(value, dict): 
       dicts.append(value) 
      elif isinstance(value, basestring) and len(value) > 0: 
       values.append(value) 

    return values 


def main(): 
    parameters = { 
     "date": {'date': "2015-12-13"}, 
     "name": "Nick", 
     "product": "BT Adapter", 
     "transaction-id": "" 
    } 

    print(magic(parameters)) 


if __name__ == '__main__': 
    main() 
4

filter 기능을 잘못 사용하고 있습니다. filter에 대한 인수는 술어이며, 참/거짓 값을 반환하는 함수이고 필터는 두 번째 인수에서 요소 을 반환하며 그 함수는 true를 반환합니다. 예를 들어

는 :

print(list(filter(lambda x: 5, [1,2,3,4,5]))) 
[1, 2, 3, 4, 5] 

bool(5) == True 때문에 필터는 모든 요소를 ​​반환한다.

두 번째 인수로 parameters.values() 값을 전달 했으므로 조건부 필터 만 통과하여 예상되는 결과를 얻을 수있는 방법이 없습니다.

from itertools import chain 

def listify(value): 
    if isinstance(value, dict): 
     return value.values() 
    elif value: 
     return [value] 
    return() 

print(list(chain.from_iterable(map(listify, parameters.values())))) 

그래서 먼저 순서로 값을 변환하고 당신이 그들을 chain.from_iterable를 사용하여 연결할 : 당신이 원하는 무엇

뭔가 같다.

빈 값은 listify에 의해 제거됩니다.이 경우 빈 시퀀스가 ​​반환되기 때문입니다. 샘플 실행 : 또한

In [2]: parameters = { 
    ...: "date": {'date':"2015-12-13"}, 
    ...: "name": "Nick", 
    ...: "product": "BT Adapter", 
    ...: "transaction-id": "" 
    ...: } 

In [3]: print(list(chain.from_iterable(map(listify, parameters.values())))) 
['2015-12-13', 'Nick', 'BT Adapter'] 

: 그렇게 단지 def를 사용하고 올바르게 쓰기, 중첩 된 조건문과 복잡한 람다 함수를 작성하는 이해가되지 않습니다. lambda은 매우 짧은 경우에만 괜찮습니다.

2

filter과 함께 map 작업을 수행하려고하는 것처럼 보였습니다. 약간의 오해가있었습니다. 필터의 기능은 기본적으로 두 번째 인수에 특정 값을 유지할지 여부를 결정 True 또는 False을 반환해야합니다, 그래서 의미가 이런 식으로 필터링하지 않습니다

filter(lambda x: x if len(x) > 0 and type(x) is not dict else None, parameters.values()) 

더 나은 :

filter(lambda x: len(x) > 0 and type(x) is not dict, parameters.values()) 
# better idiom 
filter(lambda x: len(x) > 0 and not isinstance(x, dict), parameters.values()) 

이것은 특히 다음 시도에서 해당됩니다. map 필터 기능을 시도합니다.

  1. 것은 빈 문자열/목록 사전의
  2. 값 가져 오기

는 당신이 필요로하는 경우의가, 대신 해보자 (lex(x) < 1 아무것도)를 제거합니다 : 그것은 두 단계의 과정으로 생각할 것이 좋습니다 filter을 사용하십시오.

list(map(lambda x: list(x.values()) if isinstance(x, dict) else x, filter(lambda x: len(x) > 0, parameters.values()))) 

이 생산 :

[['2015-12-13'], 'BT Adapter', 'Nick'] 

이 전혀 파이썬되지 않습니다 : filtermap 훨씬 더 많이 나는 추한 list 캐스팅을 많이 할 필요가 있다는 것을 의미 Python3을 사용하고 있습니다

[list(v.values()) if isinstance(v, dict) else v for v in parameters.values() if len(v) > 0] 

당신이 또한 사전 값을받은 후 목록을 평평하게해야하는 경우 알려줘 : 다음과 같은 지능형리스트에 집에서 에스.

0
그것은 마지막 속성 길이이 당신을 위해 일하는 것이 0

때문에 "트랜잭션 ID"를 실패

:

print filter(lambda x: x if len(x) >= 0 and type(x) is not dict else map(lambda y: x[y], x.keys()), parameters.values())