我有一个字符串列表,例如:
['z+2-44', '4+55+z+88']
如何在列表中拆分此字符串,使其类似于
[['z','+','2','-','44'],['4','+','55','+','z','+','88']]
我已尝试使用split
方法但是将44分为4和4,我不知道还有什么可以尝试。
答案 0 :(得分:26)
您可以使用正则表达式:
import re
lst = ['z+2-44', '4+55+z+88']
[re.findall('\w+|\W+', s) for s in lst]
# [['z', '+', '2', '-', '44'], ['4', '+', '55', '+', 'z', '+', '88']]
\w+|\W+
匹配一个模式,该模式包含单词字符(在您的情况下为字母数字值)或非单词字符(在您的情况下为+-
符号)。
答案 1 :(得分:14)
这将有效,使用itertools.groupby
z = ['z+2-44', '4+55+z+88']
print([["".join(x) for k,x in itertools.groupby(i,str.isalnum)] for i in z])
输出:
[['z', '+', '2', '-', '44'], ['4', '+', '55', '+', 'z', '+', '88']]
它只是将字符分组,如果它们是字母数字(或不是字母数字),只需将它们加入列表理解中即可。
编辑:带有括号的计算器的一般情况已被要求作为后续问题here。如果z
如下:
z = ['z+2-44', '4+55+((z+88))']
然后我们得到了之前的分组:
[['z', '+', '2', '-', '44'], ['4', '+', '55', '+((', 'z', '+', '88', '))']]
在令牌方面解析起来并不容易。因此,只有在使用alphanum时才会更改为join
,如果不是,则列出最后使用chain.from_iterable
进行展平:
print([list(itertools.chain.from_iterable(["".join(x)] if k else x for k,x in itertools.groupby(i,str.isalnum))) for i in z])
产生:
[['z', '+', '2', '-', '44'], ['4', '+', '55', '+', '(', '(', 'z', '+', '88', ')', ')']]
(请注意,备用正则表达式答案也可以这样调整:[re.findall('\w+|\W', s) for s in lst]
(注意+
之后缺少W
"".join(list(x))
也比"".join(x)
略快,但是我允许你添加它以避免改变已经复杂的表达式的可见性。
答案 2 :(得分:6)
使用re.split函数的替代解决方案:
l = ['z+2-44', '4+55+z+88']
print([list(filter(None, re.split(r'(\w+)', i))) for i in l])
输出:
[['z', '+', '2', '-', '44'], ['4', '+', '55', '+', 'z', '+', '88']]
答案 3 :(得分:5)
您只能在列表理解中使用str.replace()
和str.split()
内置函数:
In [34]: lst = ['z+2-44', '4+55+z+88']
In [35]: [s.replace('+', ' + ').replace('-', ' - ').split() for s in lst]
Out[35]: [['z', '+', '2', '-', '44'], ['4', '+', '55', '+', 'z', '+', '88']]
但请注意,对于较长的字符串,这不是一种有效的方法。在这种情况下,最好的方法是使用正则表达式。
作为另一种pythonic方式,您还可以使用tokenize
模块:
In [56]: from io import StringIO
In [57]: import tokenize
In [59]: [[t.string for t in tokenize.generate_tokens(StringIO(i).readline)][:-1] for i in lst]
Out[59]: [['z', '+', '2', '-', '44'], ['4', '+', '55', '+', 'z', '+', '88']]
Python comparison operators chaining模块为Python源代码提供了一个词法扫描程序,用Python实现。此模块中的扫描仪也将注释作为标记返回,这使得它可用于实现“漂亮的打印机”,包括用于屏幕显示的着色器。
答案 4 :(得分:-1)
如果你想坚持使用split
(因此避免使用正则表达式),你可以为它提供一个可选字符来分割:
>>> testing = 'z+2-44'
>>> testing.split('+')
['z', '2-44']
>>> testing.split('-')
['z+2', '44']
所以,你可以通过链接拆分命令来鞭打一些东西。
但是,使用正则表达式可能更具可读性:
import re
>>> re.split('\+|\-', testing)
['z', '2', '44']
这只是说"将字符串拆分为任何+或 - 字符" (反斜杠是转义字符,因为它们在正则表达式中都有特殊含义。
最后,在这种特殊情况下,我认为目标是"在每个非字母数字字符处分开",在这种情况下,正则表达式仍然可以节省一天:
>>> re.split('[^a-zA-Z0-9]', testing)
['z', '2', '44']
当然值得注意的是,正如其他一些SO讨论所讨论的那样,还有其他一百万个解决方案。
Python: Split string with multiple delimiters
Split Strings with Multiple Delimiters?
我的答案是针对简单易读的代码,而不是表现,以纪念Donald Knuth