简体   繁体   English

展平字符串列表的列表

[英]Flatten list of list of strings

I have this list:我有这个清单:

list1 = ["['word']", "['second', 'first']", "['first']"]

You can see it's not exactly a list of list of strings as the items were converted into strings.您可以看到它不完全是字符串列表,因为项目已转换为字符串。

I want to have this flattened output:我想要这个扁平化的输出:

list2 = ['word', 'second', 'first', 'first']

Just a simple list of strings.只是一个简单的字符串列表。

I 've tried using this way:我试过用这种方式:

list2 = [ x.strip('[]') for x in list1]

But the issue is with the second item still considered as one item:但问题在于第二项仍被视为一项:

["'word'", "'second', 'first'", "'first'"]

So I tried splitting by comma:所以我尝试用逗号分割:

list3 = [item.split(',') for x in list2 for item in x]

But it gave this output:但它给出了这个输出:

[["'"],
 ['w'],
 ['o'],
 ['r'],
 ['d'],
 ["'"],
 ["'"],
 ['s'],
 ['e'],
 ['c'],
 ['o'],
 ['n'],
 ['d'],
 ["'"],
 ['', ''],
 [' '],
 ["'"],
 ['f'],
 ['i'],
 ['r'],
 ['s'],
 ['t'],
 ["'"],
 ["'"],
 ['f'],
 ['i'],
 ['r'],
 ['s'],
 ['t'],
 ["'"]]

Any idea how to fix this?知道如何解决这个问题吗?

UPDATES - SOLUTION更新 - 解决方案

With help from @AKX在@AKX 的帮助下

list2 = [ast.literal_eval(item) for item in list1]

Then using this function:然后使用这个函数:

def flatten(lst):
    for el in lst:
        if isinstance(el, list):
            yield from el
        else:
            yield el

list3 = flatten(list2)
list(list3)

This gives:这给出:

['word', 'second', 'first', 'first']

UPDATE 2更新 2

An optimized and alternative solution from @waynelpu instead of flatten function, just use:来自@waynelpu 的优化和替代解决方案而不是flatten功能,只需使用:

list2 = [inner for item in list1 for inner in ast.literal_eval(item)] 

If you have a list of strings of Python expressions that represent lists (how's that for a nested clause), you will have to use ast.literal_eval() to get back to reality, as it were.如果您有一个表示列表的 Python 表达式字符串列表(嵌套子句如何),您将不得不使用ast.literal_eval()回到现实,就像它一样。

>>> import ast
>>> list1 = ["['word']", "['second', 'first']", "['first']"]
>>> list2 = [ast.literal_eval(item) for item in list1]
[['word'], ['second', 'first'], ['first']]

Using ast.literal_eval() , as opposed to the dangerous eval() that you shouldn't use is safe, as it only evaluates literals that can have no side effects.使用ast.literal_eval() ,而不是你不应该使用危险eval()是安全的,因为它只评估没有副作用的文字。

list1 = ["['word']", "['second', 'first']", "['first']"]
new_lst = [sub_val for val in list1 for sub_val in eval(val)]
print new_lst

Result:['word', 'second', 'first', 'first']

You can also use more_itertools.flatten你也可以使用more_itertools.flatten

from more_itertools import flatten
import ast

list1 = ["['word']", "['second', 'first']", "['first']"]
list(flatten(ast.literal_eval(item) for item in list1))

Output:输出:

['word', 'second', 'first', 'first']

This is another solution:这是另一种解决方案:

import re
list1 = ["['word']", "['second', 'first']", "['first']"]
pattern = re.compile(r'\w+')
m = pattern.findall(str(list1))

Result:结果:

['word', 'second', 'first', 'first']

In order to flatten everything use itertools.chain.from_iterable :为了扁平化所有内容,请使用itertools.chain.from_iterable

>>> import itertools
>>> import ast
>>> list1 = ["['word']", "['second', 'first']", "['first']"]
>>> list2 = list(itertools.chain.from_iterable(map(ast.literal_eval, list1)))
>>> list2
['word', 'second', 'first', 'first']

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

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