查找字符串中的列表

2024-10-05 14:25:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我看到了很多在字符串中查找字符串或在列表中查找字符串的示例,但是如何在字符串中查找列表呢。例如,我有一个包含数据列的csv文件,最后一列不是字符串就是列表。下面是仅显示最后3列的数据子集。你知道吗

TRUE, 93877, S26476961
TRUE, 93878, ['S26489167', 'S26492524']
FALSE, 93879, S26476962
FALSE, 93880, ['S26489168', 'S26492527', 'S26492528']

起初,我试图用逗号来解析csv文件的每一行,但它会解析列表中的逗号(创建额外的列)。我只希望列表被识别为一个单一的数据块,这样我就可以将它作为一个n项的列表来处理。 @TemporalWolf的评论非常有用,因为如果我使用csv模块(特别是csv.reader文件)所以。。。你知道吗

reader = csv.reader(inFile)
for row in reader:
    print(row)

它将列表保存在一列中。现在的问题仍然是,它只是一个字符串。换句话说,row[n][0]返回左括号([),但我想把它放入一个列表中。你知道吗


Tags: 文件csv数据字符串falsetrue示例列表
3条回答

这是相反的方法。它通过检查行的项中的前导[和尾随]csv.reader返回的数据中查找列表。你知道吗

import csv 

def find_lists(row):
    sublist = []
    for item in row:
        if not sublist:
            if item.startswith('['):
                if item.endswith(']'):
                    yield [item[1:-1]]
                else:
                    sublist.append(item[1:])
            else:
                yield item
        else:
            if item.endswith(']'):
                sublist.append(item[:-1])
                yield sublist
                sublist = []
            else:
                sublist.append(item)
    for item in sublist:
        yield item

with open('test.csv') as infile:
    reader = csv.reader(infile, skipinitialspace=True)
    for row in reader:
        print(list(find_lists(row)))

这依赖于引用列表元素的'字符。使用此信息,它仅在逗号上拆分,而不是在该字符后面或前面,使用正则表达式:

import re
import pandas as pd
import io


text = """TRUE, 93877, S26476961
TRUE, 93878, ['S26489167', 'S26492524']
FALSE, 93879, S26476962
FALSE, 93880, ['S26489168', 'S26492527', 'S26492528']"""

with io.StringIO(text) as f:
    for line in f:
        print(re.split("(?<!'), (?!')", line.strip()))


# ['TRUE', '93877', 'S26476961']
# ['TRUE', '93878', "['S26489167', 'S26492524']"]
# ['FALSE', '93879', 'S26476962']
# ['FALSE', '93880', "['S26489168', 'S26492527', 'S26492528']"]

# Or with pandas

with io.StringIO(text) as f:
    print(pd.read_csv(f,
                  header=None,
                  sep="(?<!'), (?!')",
                  engine='python'))

#        0      1                                        2
# 0   True  93877                                S26476961
# 1   True  93878               ['S26489167', 'S26492524']
# 2  False  93879                                S26476962
# 3  False  93880  ['S26489168', 'S26492527', 'S26492528']

编辑:

如果您使用的是python2,则需要将文本转换为unicode(将字符u放在文本之前)才能使用io.StringIO

import re
import pandas as pd
import io


text = u"""TRUE, 93877, S26476961
TRUE, 93878, ['S26489167', 'S26492524']
FALSE, 93879, S26476962
FALSE, 93880, ['S26489168', 'S26492527', 'S26492528']"""

with io.StringIO(text) as f:
    for line in f:
        print(re.split("(?<!'), (?!')", line.strip()))


# ['TRUE', '93877', 'S26476961']
# ['TRUE', '93878', "['S26489167', 'S26492524']"]
# ['FALSE', '93879', 'S26476962']
# ['FALSE', '93880', "['S26489168', 'S26492527', 'S26492528']"]

# Or with pandas

with io.StringIO(text) as f:
    print(pd.read_csv(f,
                  header=None,
                  sep="(?<!'), (?!')",
                  engine='python'))

#        0      1                                        2
# 0   True  93877                                S26476961
# 1   True  93878               ['S26489167', 'S26492524']
# 2  False  93879                                S26476962
# 3  False  93880  ['S26489168', 'S26492527', 'S26492528']

编辑2:

如果不希望依赖引号字符',可以尝试以下操作:

import ast
import re


with io.StringIO(text) as f:
    for line in f:
        parts = re.split(", (?=\[)", line.strip())
        line = []
        for part in parts:
            if all(char in part for char in ('[]')):
                line.append(ast.literal_eval(part))
            else:
                line += part.split(", ")
        print(line)

将位于左方括号前的逗号拆分,然后按如下方式检查结果:

  1. 检查拆分操作生成的列表中的每个元素是否都有方括号。如果是这样,则将其转换为带有ast.literal_evallist对象,并将其添加到最终输出列表中。你知道吗
  2. 否则,在逗号上拆分,并将随后的列表添加到最终输出列表中。你知道吗

这应该得到与上述解决方案相同的结果。你知道吗

我希望这有帮助。你知道吗

这里有一个有趣的解决方案:用逗号分隔每一行,并尝试将每个部分作为Python代码进行解析。如果它是无效的,这意味着我们不包括整个列表:

import ast

def get_columns(line):
    def valid(code):
        try:
            ast.parse(code.strip())
        except SyntaxError:
            return False
        return True
    sections = line.split(',')
    columns = []
    for i, section in enumerate(sections):
        if i == len(sections) - 1 or valid(section):
            columns.append(section)
        else:
            sections[i + 1] = ','.join([section, sections[i + 1]])
    return columns

with open(inFile) as f:
    for line in f:
        for column in get_columns(line):
            print(column)

由于这不涉及正则表达式的确切情况,这是相当普遍的。还要注意的是,由于数据文件中的“代码”都没有经过评估来执行测试,所以这是完全安全的。你知道吗

使用python2和python3。你知道吗

相关问题 更多 >