列表理解的意外输出

时间:2018-01-02 15:42:18

标签: python python-3.x list list-comprehension

我有一个输入列表如下:

test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']

我需要展平,所以摆脱元组和列表作为test_list的第二和第三元素

预期产出:

['a', 'abc', 'd', 'efgh', 'i', 'jkl']

我在找到正确的列表理解方面遇到了问题。 我尝试了以下两个例子:

result = [xs if type(xs) is str else x for xs in test_list for x in xs]
print('result', result) 
# this outputs:
# ['a', 'abc', 'd', 'efgh', 'i', 'jkl', 'jkl', 'jkl']

result = [x if ((type(xs) is list) or (type(xs) is tuple)) else xs for xs in test_list for x in xs]
print('result',result)
#this also outputs:
# ['a', 'abc', 'd', 'efgh', 'i', 'jkl', 'jkl', 'jkl']  

正如您所看到的,它确实“展平”了列表,但它会根据最后一个元素中的字符数重复最后一个元素。示例test_list的最后一个元素是'jklm',然后result中的最后一个元素重复4次。

我想知道是否有列表理解将我的输入列表展平到预期的输出而不重复最后一个元素。

5 个答案:

答案 0 :(得分:7)

以下嵌套理解将起作用:

[x for sub in test_list for x in (sub if isinstance(sub, (list, tuple)) else [sub])]

这使用的isinstance优先于type(...),并且可以提供多种类型。如果任何顶级元素不是列表或元组,则它将包含在列表中。

答案 1 :(得分:4)

您可以尝试:

test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
result = [x for xs in test_list for x in (xs if isinstance(xs, (tuple, list)) else [xs])]

但是我不会使用它,我只会写一个for循环

答案 2 :(得分:2)

您始终可以将-stop:中的所有单个元素转换为列表:

test_list

然后用itertools.chain_from_iterable

展平
>>> test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
>>> convert_to_lists = [[x] if not isinstance(x, (list, tuple)) else x for x in test_list]
>>> convert_to_lists
[['a'], ('abc', 'd'), ['efgh', 'i'], ['jkl']]

或全部在一行:

>>> from itertools import chain
>>> list(chain.from_iterable(convert_to_lists))
['a', 'abc', 'd', 'efgh', 'i', 'jkl']

答案 3 :(得分:0)

使用 for 循环和 function 以备将来使用。 添加了原语而不是类型。 在 , 拆分,您可以根据自己的要求进行更改

list_1 = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl', {2,2.5}] 

def to_flatten(my_list, primitives=(bool, str, int, float)):
    
    flatten = []
    my_list = [stuff.split(',') if type(stuff) == str else stuff for stuff in list_1]
    
    for item in my_list:
        if isinstance(item, primitives):
            flatten.append(item)
        else:
            flatten.extend(item)
    return flatten
   
print(to_flatten(list_1))

给予

['a', 'abc', 'd', 'efgh', 'i', 'jkl', 2, 2.5]

[Program finished]

答案 4 :(得分:0)

您可以使用 join() 方法

>>> test_list = ['a', ('abc', 'd'), ['efgh', 'i'], 'jkl']
>>> ",".join([",".join(i) if type(i) in [list,tuple] else i for i in test_list]).split(",")
['a', 'abc', 'd', 'efgh', 'i', 'jkl']
>>>