如何从具有默认值的字符串列表中解析(可能未知)键/值对?

2024-10-03 02:44:44 发布

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

我在Pandas数据框中有一个字符串列,其中包含数据库设置,我想将键/值对转换为数据帧中的新列,用True填充任何缺少的值。在

下面是其中一个字符串的外观:

Status=ONLINE, Updateability=READ_WRITE, UserAccess=MULTI_USER, Recovery=SIMPLE, Version=706, Collation=SQL_Latin1_General_CP1_CI_AS, SQLSortOrder=52, IsAutoCreateStatistics, IsAutoUpdateStatistics, IsFullTextEnabled

我希望输出看起来像:

^{pr2}$

我尝试遍历这些行,用re.subsplit()解析字符串,这使我找到了遵循key=value格式的设置的键/值对。我硬编码了已知的布尔键(如下面的代码所示),但我希望对未知的布尔值进行此项工作。在

我现在要讨论的问题是将特定键/值对的结果回滚到它应该进入的正确列/行。在

^{3}$

让我落网:

[[{'Status': 'ONLINE'},
  {'Updateability': 'READ_WRITE'},
  {'UserAccess': 'MULTI_USER'},
  {'Recovery': 'SIMPLE'},
  {'Version': '706'},
  {'Collation': 'SQL_Latin1_General_CP1_CI_AS'},
  {'SQLSortOrder': '52'},
  {'IsAutoCreateStatistics': 'True'},
  {'IsAutoUpdateStatistics': 'True'},
  {'IsFullTextEnabled': 'True'}],
 [{'Status': 'OFFLINE'},
  {'Updateability': 'READ'},
  {'UserAccess': 'SINGLE_USER'},
  {'Recovery': 'SIMPLE'},
  {'Version': '706'},
  {'Collation': 'SQL_Latin1_General_CP1_CI_AS'},
  {'SQLSortOrder': '53'},
  {'IsAutoCreateStatistics': 'True'},
  {'IsAutoUpdateStatistics': 'True'},
  {'IsTornPageDetectionEnabled': 'True'}]]

这是迄今为止我想出的最好的方法,看起来我很接近,但我相信有一种比Python更能做到这一点的方法。在


Tags: 字符串truereadsqlversionstatussimplegeneral
3条回答

如果您知道字符串是这样的,可以执行以下操作:

your_string = 'Status=ONLINE, Updateability=READ_WRITE, ThisValueWillBeTrue'
your_list = your_string.split(sep=', ')
your_dict = {i.split(sep='=')[0] : i.split(sep='=')[1] if len(i.split(sep='=')) > 1 else True for i in your_list}

在Padraic Cunninghams的回答上,我想出了这个解决方案。根据输入的格式约束,此带有正则表达式的解决方案可能比拆分/剥离解决方案更健壮或更弱。在

import pandas
import re

def repl(s):
    for sub in re.findall('[\w=]+', s):
        k, _, v = sub.partition("=")
        if v:
            yield k,v
        else:
            yield k, "True"

_status = [ 'Status=ONLINE1, IsFullTextEnabled', 
            'Status=ONLINE2, IsFullTextEnabled']

data = []
for _row in _status:
    data.append(dict(repl(_row)))

print(pandas.DataFrame(data))

您可以使用简化操作结构分区,不需要任何正则表达式,只需拆分字符串:

s = "Status=ONLINE, Updateability=READ_WRITE, UserAccess=MULTI_USER, Recovery=SIMPLE, Version=706, Collation=SQL_Latin1_General_CP1_CI_AS, SQLSortOrder=52, IsAutoCreateStatistics, IsAutoUpdateStatistics, IsFullTextEnabled"

def repl(s):
    for sub in s.split(", "):
        k, _, v = sub.partition("=")
        yield (k, v) if v else (k, "True")

=上分区时,如果在=上有一个空字符串,则表示我们没有配对,因此我们不需要也不需要关心潜在密钥的任何先验知识:

^{pr2}$

另外,如果空格可能不存在,您可以在","上拆分并去掉空白,或者使用csvlib settinskipinitialspace=True,它将处理"foo, bar""foo,bar"

from csv import reader
from itertools import chain

def repl(s):
    for sub in chain(*reader([s], skipinitialspace=True)):
        k, _, v = sub.partition("=")
        yield (k, v) if v else (k, "True")


print(dict(repl(s)))

如果您只想创建一个新的df,并且所有的键都相同:

from csv import reader
from itertools import chain
import pandas as pd

def repl(s):
    d = {}
    for sub in chain(*reader([s], skipinitialspace=True)):
        k, _, v = sub.partition("=")
        d[k] = v if v else "True"
    return d




df =  pd.DataFrame.from_records(map(repl ,status))

print(df)

但是根据讨论,如果您稍后看到第一个dict中没有的键,那么您将得到not True的行值的nan

相关问题 更多 >