Python 将字符串拆分为各种数据类型

Python 将字符串拆分为各种数据类型,python,string,list,Python,String,List,我想转换以下字符串: s = '1|2|a|b' 到 可以在一行中进行转换吗 可以在一行中进行转换吗 是,这是可能的。但是怎么做呢 该方法的算法 使用将字符串拆分为其组成部分。这个的输出是 >>> s = '1|2|a|b' >>> s.split('|') ['1', '2', 'a', 'b'] 现在我们已经解决了一半的问题。接下来,我们需要循环分割字符串,然后检查它们是字符串还是int A,用于循环部分 用于查找元素是int还是str 列表理

我想转换以下字符串:

s = '1|2|a|b'

可以在一行中进行转换吗

可以在一行中进行转换吗

,这是可能的。但是怎么做呢

该方法的算法

  • 使用将字符串拆分为其组成部分。这个的输出是

    >>> s = '1|2|a|b'
    >>> s.split('|')
    ['1', '2', 'a', 'b']
    
  • 现在我们已经解决了一半的问题。接下来,我们需要循环分割字符串,然后检查它们是字符串还是int

    • A,用于循环部分
    • 用于查找元素是
      int
      还是
      str
  • 列表理解可以很容易地写成
    [s.split(“|”)中的i代表i]
    。但是我们如何在那里添加
    if
    子句呢?这是一本书。现在我们知道了哪些元素是
    int
    ,哪些不是,我们可以很容易地调用它的内置元素

    因此,最终的代码如下所示

      [int(i) if i.isdigit() else i for i in s.split('|')]
    
现在来看一个小演示

>>> s = '1|2|a|b'
>>> [int(i) if i.isdigit() else i for i in s.split('|')]
[1, 2, 'a', 'b']
如我们所见,输出与预期一致



请注意,如果有许多类型需要转换,则此方法不适用。

您不能在一行中对负数或大量混合类型执行此操作,但您可以使用适用于多种类型的函数,使用:


如果允许使用辅助函数,则可以“在一行中”执行任意多个或复杂的转换。Python本机没有“将此字符串转换为它应该表示的类型”函数,因为它“应该”表示的内容是模糊的,可能会随着应用程序的不同而变化

def convert(input):
    converters = [int, float, json.loads]
    for converter in converters:
        try:
            return converter(input)
        except (TypeError, ValueError):
            pass
    # here we assume if all converters failed, it's just a string
    return input

s = "1|2.3|a|[4,5]"
result = [convert(x) for x in s.split("|")]

另一种方法是使用
map
内置方法:

>>> s='1|2|a|b'
>>> l = map(lambda x: int(x) if x.isdigit() else x, s.split('|'))
>>> l
[1, 2, 'a', 'b']
如果是Python3,则:

>>> s='1|2|a|b'
>>> l = list(map(lambda x: int(x) if x.isdigit() else x, s.split('|')))
>>> l
[1, 2, 'a', 'b']

由于Python3中的
map
将提供一个生成器,因此如果您有各种数据类型(超过str和int),则必须将其转换为
list
,我相信这可以完成这项工作

s = '1|2|a|b|[1, 2, 3]|(1, 2, 3)'
print [eval(x) if not x.isalpha() else x for x in s.split("|")]

# [1, 2, 'a', 'b', [1, 2, 3], (1, 2, 3)]

如果存在诸如“b1”之类的元素,则此操作将失败。

更复杂的数据类型如何?您希望有多少种数据类型?你试过什么吗?你的代码有什么特别的问题吗?为什么你要在一行中做这件事?@vaultah一开始,只是
int
string
,但我也在考虑如何使用
float
的解决方案。这就是pythonic。那么,也许你可以建议一些改进的方法?我不知道这其中的哪一部分对你来说如此离谱。我不想冒犯你,但在我看来,一堆尝试例外根本不是一个好的做法。建议我说,对类型进行harcoding是一个糟糕的级别解决方案,也许有一个注册类型的列表来转换会更好。好的建议。我已经改进了答案,使之适合。感谢您建议
ast.literal\u eval
。这是非常有用的。现在,我可以使用两行代码转换为多种类型:
从ast导入literal\u eval
[literal\u eval(e)如果e[-1].isdigit()或者e在s.split(''124;')中表示e。
@wannik不用担心,如果你想要一行代码,你可以尝试
列表(map(literal\u eval,re.sub('(?!\\\124;)([a-Za-z]+),““+r”+”),s.split('r“+”),“)/code>),将字符用引号括起来,但是函数方法更健壮。这里确实不需要映射lambda。
>>> s='1|2|a|b'
>>> l = list(map(lambda x: int(x) if x.isdigit() else x, s.split('|')))
>>> l
[1, 2, 'a', 'b']
s = '1|2|a|b|[1, 2, 3]|(1, 2, 3)'
print [eval(x) if not x.isalpha() else x for x in s.split("|")]

# [1, 2, 'a', 'b', [1, 2, 3], (1, 2, 3)]