我有一个由字符串或字典组成的字典
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'
。
如何提取所有值?
答案 0 :(得分:4)
您滥用filter
功能。 filter
的参数是谓词,它是一个返回true / false值的函数,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']
另外:用嵌套条件写一个复杂的lambda函数没有意义,所以只需使用def
并正确编写即可。 lambda
只有在非常短的情况下才适用。
答案 1 :(得分:2)
在我看来,您正试图对map
进行filter
操作,显示出一点误会。过滤器中的函数本质上必须返回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())
对于您的下一次尝试尤其如此,该尝试尝试{/ 1}} 内部过滤器功能。最好将此视为一个两步过程:
map
)如果您需要使用lex(x) < 1
,请尝试使用此功能。我正在使用Python3,这意味着我必须做很多丑陋的filter
投射:
list
这会产生:
list(map(lambda x: list(x.values()) if isinstance(x, dict) else x, filter(lambda x: len(x) > 0, parameters.values())))
这根本不是pythonic:[['2015-12-13'], 'BT Adapter', 'Nick']
和filter
在列表推导中更像是以下内容:
map
如果您在获取字典值后还需要展平列表,请告诉我。
答案 2 :(得分: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()
答案 3 :(得分:0)
最后一个属性“transaction-id”失败,因为它的长度为0。
这对你有用:
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())