假设我有一本字典
kwargs = {'key1': 1,
'key2': 2,
'key3list': [1,2,3,4]}
其中任何键的值之一可以是整数列表,而其他键只是任何对象,在本例中是整数。我希望,在一行(或最多一对)中,将键的所有值放入一个元组中,解压缩所有可能的列表。请注意,通过如何构造字典kwargs
,具有列表的键将具有以“list”结尾的键。
我想出了以下内容:
a = tuple(
[kwargs[key] if not key.endswith('list') else *kwargs[key] for key in kwargs.keys()]
)
但是我收到的错误是我无法解压*kwargs[key]
这里..
我该如何解决这个问题?
答案 0 :(得分:3)
如果您不必使用列表理解,可以使用生成器:
def flat(l):
for k, v in l.items():
if type(v) == list:
for x in v:
yield x
else:
yield v
kwargs = {'key1': 1,
'key2': 2,
'key3list': [1,2,3,4]}
print(tuple(flat(kwargs)))
输出:
(1, 2, 1, 2, 3, 4)
请注意,dict
没有顺序,因此生成的元组可以根据items()
返回字典项的顺序进行更改。
答案 1 :(得分:3)
可以使用嵌套列表comp完成,但它并不漂亮。一种方法是将非列表项包装到列表中,然后解压缩生成的2D列表。
kwargs = {
'key1': 1,
'key2': 2,
'key3list': [1, 2, 3, 4],
}
a = [u for v in
[val if key.endswith('list') else [val] for key, val in kwargs.items()]
for u in v]
print(a)
<强>输出强>
[1, 2, 1, 2, 3, 4]
我认真建议在这里使用传统的循环技术,不要尝试在列表组件中完成所有操作。例如,
a = []
for key, val in kwargs.items():
if key.endswith('list'):
a.extend(val)
else:
a.append(val)
print(a)
以上代码可以写成
a = []
for key, val in kwargs.items():
meth = a.extend if key.endswith('list') else a.append
meth(val)
但即使这样也有点过于聪明&#34;,并且比以前版本的可读性差。
我们可以通过忽略键并测试当前对象是否为列表来使代码更通用:
a = []
for val in kwargs.values():
if isinstance(val, list):
a.extend(val)
else:
a.append(val)
正如Lutz Horn所说,如果输出列表的顺序很重要,这种解包策略有点危险,因为传统上在Python中,普通字典并不一定保留插入顺序。但是在Python 3.6+中,dicts 做保留顺序,所以这种技术是安全的,但它仍然让我有点不舒服。 ;)