[英]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?知道如何解决这个问题吗?
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']
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.