简体   繁体   English

Python无法使用三元运算符在列表理解中使用拆包

[英]Python cannot use unpacking in list comprehension with ternary operator

suppose I have a dictionary 假设我有一本字典

kwargs = {'key1': 1, 
          'key2': 2,
          'key3list': [1,2,3,4]}

Where one of the values of any of the keys could be a list of integers, while the others would just be any object, in this case, an integer. 其中任何键的值之一可以是整数列表,而其他键只是任何对象,在这种情况下为整数。 I want to, in a single line (or in a couple at most) , put all the values of the keys into one tuple, unpacking all possible lists. 我想在一行(或最多两行)中,将键的所有值放入一个元组,以解压缩所有可能的列表。 Notice that by how the dictionary kwargs is constructed, keys having a list will have the key ending with 'list'. 请注意,通过构造字典kwargs方式,具有列表的键将具有以'list'结尾的键。

I came up with the following: 我想出了以下几点:

a = tuple(
[kwargs[key] if not key.endswith('list') else *kwargs[key] for key in kwargs.keys()]
)

However I get the error that I cannot unpack *kwargs[key] here.. 但是我收到一个错误,我不能在这里解压*kwargs[key]

How could I fix this? 我该如何解决?

If you don't have to use list comprehension, a generator could be used: 如果您不必使用列表推导,则可以使用生成器:

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)))

Output: 输出:

(1, 2, 1, 2, 3, 4)

Note that the dict has no order so the resulting tuple can change based on the order that items() returns the dictionary items. 请注意, dict没有顺序,因此结果元组可以根据items()返回字典项的顺序进行更改。

It can be done using a nested list comp, but it's not pretty. 可以使用嵌套列表comp来完成,但这并不漂亮。 One way is to wrap non-list items into lists, and then unpack the resulting 2D list. 一种方法是将非列表项包装到列表中,然后解压缩生成的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)

output 输出

[1, 2, 1, 2, 3, 4]

I seriously recommend using traditional looping techniques here, don't try to do it all in a list comp. 强烈建议在这里使用传统的循环技术,不要试图在列表组合中全部完成操作。 Eg, 例如,

a = []
for key, val in kwargs.items():
    if key.endswith('list'):
        a.extend(val)
    else:
        a.append(val)

print(a)

The above code can be written as 上面的代码可以写成

a = []
for key, val in kwargs.items():
    meth = a.extend if key.endswith('list') else a.append
    meth(val)

But even that is a bit too "clever", and less readable than the previous version. 但是即使那样也有点“聪明”,比以前的版本可读性差。


We can make the code a little more general by ignoring the keys and testing if the current object is a list or not: 我们可以通过忽略键并测试当前对象是否为列表来使代码更通用:

a = []
for val in kwargs.values():
    if isinstance(val, list):
        a.extend(val)
    else:
        a.append(val)

As Lutz Horn notes, this unpacking strategy is a little dangerous if the order of the output list is important, since traditionally in Python a plain dict doesn't necessarily retain insertion order. 正如Lutz Horn指出的那样,如果输出列表的顺序很重要,那么这种拆包策略会有些危险,因为传统上在Python中,简单的dict不一定会保留插入顺序。 However in Python 3.6+, dicts do retain order, so this technique is safe, but it still makes me a little uncomfortable. 但是在Python 3.6+中,字典确实保留了顺序,因此此技术是安全的,但仍然使我有些不舒服。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM