首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Python中的字符串中提取infor并返回一个列表

从Python中的字符串中提取infor并返回一个列表
EN

Stack Overflow用户
提问于 2021-10-28 13:02:15
回答 3查看 70关注 0票数 1

我正在研究一个大型数据集,并将我的分析从Matlab/Octave转移到Python。这些文件是按文件夹/目录组织的,每个目录名都包含有关数据的基本信息。在Matlab中,我从文件夹名中提取该信息。我也想用Python来做同样的事情。我对Python略知一二,但我肯定不是功夫大师。

米维

代码语言:javascript
复制
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个元素时,会出现问题。

如果语法在我命名的方式上不正确,请道歉。我可能把列表和数组混为一谈

欢迎任何评论、更正或建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-28 13:53:59

您还可以使用下面的解决方案和regex模式来捕获最后两个可选部分的所有三个部分:

代码语言:javascript
复制
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']]        

Python演示。这是regex演示。详细信息

  • ^ -字符串的开始
  • (\d+) -第1组:一个或多个数字(因此,我们可以安全地使用int(arr[0]) )
  • L -一封L
  • (?:-(\d+(?:\.\d+)?))? -一个可选的序列
    • - -a连字符
    • (\d+(?:\.\d+)?) -第2组:一个或多个数字,然后是一个可选的.序列和一个或多个数字

  • ([_-].*)? -一个可选的组3:_-,然后是任何字符(除了没有re.DOTALL标志的换行字符),直到字符串的末尾。
票数 2
EN

Stack Overflow用户

发布于 2021-10-28 13:35:56

我认为更好的解决办法是寻找你想要匹配的模式。

我认为这将解决您的问题,并且更容易调试:

代码语言:javascript
复制
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)

输出:

代码语言:javascript
复制
[['15', '0.3'], ['16', '0.4', '_redo'], ['15', '0'], ['16', '-redo']]
票数 2
EN

Stack Overflow用户

发布于 2021-10-28 13:32:04

您可以使用re.split和一个前瞻性regex,以及一个包含帮助函数的列表理解:

代码语言:javascript
复制
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)]

产出:

代码语言:javascript
复制
[[15, 0.3], [16, 0.4, '_redo'], [15, 0], [16, '-redo']]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69754588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档