我正在研究一个大型数据集,并将我的分析从Matlab/Octave转移到Python。这些文件是按文件夹/目录组织的,每个目录名都包含有关数据的基本信息。在Matlab中,我从文件夹名中提取该信息。我也想用Python来做同样的事情。我对Python略知一二,但我肯定不是功夫大师。
米维
from re import split
file_list = ['15L-0.3', '16L-0.4_redo', '15L-0', '16L-redo']
s_f = lambda x: float(x) if isinstance(x,(int, float))\
else [split('[^0-9.]+',x,1)[0], split('0[.0-9]*',x,1)[1]]
array = [[i, [float(i.split('L',1)[0]),
s_f(i)]]for i in file_list]前面的代码不适用于file_list的所有元素,并且来自lambda的返回没有附加到数组中。我把标准的split()和re.split()版本混合在一起。但我认为标准版本不接受正则表达式。
我需要一个数组,一个列表列表,其中对于file_list的每个元素,我得到了文件夹名,即file_list中的元素。thaat子列表的第二个元素是一个数组,在16之前有一个数字,然后它可以有1或2个其他元素。在L之后的0到1之间的数字,它并不总是存在的,在这个数字之后的任何东西,甚至如果这个数字不存在的话,甚至L本身。
对于第一个元素[15, 0.3]
第二届[16, 0.4, '_redo']
第三届[15, 0]
对于第4次[16, '-redo']
我有几个逻辑阶段,因为我的实际字符串更长,并且有多个参数。我可以将它分为0到1之间的数字和/或后缀之间的不存在或存在,但是我想看看是否有一种方法可以使这个通用。
我为此写了lambda函数。如果输出是单个数字或字符串,则可以工作。当我需要输出外部列表的2个元素时,会出现问题。
如果语法在我命名的方式上不正确,请道歉。我可能把列表和数组混为一谈
欢迎任何评论、更正或建议。
发布于 2021-10-28 13:53:59
您还可以使用下面的解决方案和regex模式来捕获最后两个可选部分的所有三个部分:
import re,ast
file_list = ['15L-0.3', '16L-0.4_redo', '15L-0', '16L-redo']
rx = re.compile(r'^(\d+)L(?:-(\d+(?:\.\d+)?))?([_-].*)?$')
array = []
for i in file_list:
m = rx.search(i)
if m:
arr = list(m.groups())
arr[0] = int(arr[0]) # This is an int
if arr[1]: # If Group 2 matched, it is either an int or float
arr[1] = ast.literal_eval(arr[1]) # Parse the second number as int or float
array.append([x for x in arr if x is not None]) # Remove any None values
print (array)
# => [[15, 0.3], [16, 0.4, '_redo'], [15, 0], [16, '-redo']] ^ -字符串的开始(\d+) -第1组:一个或多个数字(因此,我们可以安全地使用int(arr[0]) )L -一封L信(?:-(\d+(?:\.\d+)?))? -一个可选的序列- -a连字符(\d+(?:\.\d+)?) -第2组:一个或多个数字,然后是一个可选的.序列和一个或多个数字([_-].*)? -一个可选的组3:_或-,然后是任何字符(除了没有re.DOTALL标志的换行字符),直到字符串的末尾。发布于 2021-10-28 13:35:56
我认为更好的解决办法是寻找你想要匹配的模式。
我认为这将解决您的问题,并且更容易调试:
import re
file_list = ['15L-0.3', '16L-0.4_redo', '15L-0', '16L-redo']
new_file_list = []
for file in file_list:
split_file = re.findall(r'(?:\d+(?:\.\d+)*|[-_]redo)', file)
new_file_list.append(split_file)
print(new_file_list)输出:
[['15', '0.3'], ['16', '0.4', '_redo'], ['15', '0'], ['16', '-redo']]发布于 2021-10-28 13:32:04
您可以使用re.split和一个前瞻性regex,以及一个包含帮助函数的列表理解:
import re
regex = re.compile('[-_](?=\d)|(?=[-_]\D)')
def toint(n):
n2 = n.rstrip('L')
if n2.replace('.', '', 1).isnumeric():
return float(n2) if '.' in n2 else int(n2)
else:
return n
[[toint(i) for i in l] for l in map(regex.split, file_list)]产出:
[[15, 0.3], [16, 0.4, '_redo'], [15, 0], [16, '-redo']]https://stackoverflow.com/questions/69754588
复制相似问题