如何使用 Python 中的列表理解将字符串转换为 char 和 int 列表
How to transform a string into a list of char and int using a list comprehension in Python
给定以下字符串:
"[10,20]"
我想在 Python 中使用列表理解创建以下列表:
['[', 10, ',', 20, ']']
是 10 和 20 整数 和列表中的其余元素 字符.
我假设我需要使用类似于 itertools.groupby(iterable, key=None)
提供的东西:
Make an iterator that returns consecutive keys and groups from the
iterable. The key is a function computing a key value for each
element. If not specified or is None, key defaults to an identity
function and returns the element unchanged. Generally, the iterable
needs to already be sorted on the same key function.
然而 Python 的 group by returns 具有连续 keys 和 [=26= 的迭代器]组。在我的例子中,键会改变,所以我想我需要一个类似的迭代器,returns 基于 filter 的组。有什么想法吗?
根据该字符是否为数字进行分组。这可以使用 str.isnumeric
函数作为 groupby()
.
的 key
参数来完成
s = "[10,20]"
g = itertools.groupby(s, key=str.isnumeric)
然后,对于 True
组,将其转换为整数。离开 False
个组 as-is。
由于 groupby
的值是迭代器,其中每个元素都是一个单独的字符,因此您需要将其与 ""
连接以将其转换为单个字符串,并可选择将该字符串转换为整数。
lst = [int("".join(chars)) if is_numeric else "".join(chars) for is_numeric, chars in g]
给出:
['[', 10, ',', 20, ']']
一行:
lst = [ int("".join(chars))
if is_numeric else "".join(chars)
for is_numeric, chars in itertools.groupby(s, key=str.isnumeric)
]
这也可以使用正则表达式轻松完成。
import re
NUMCHR = re.compile(r'\d+|[^\d]') #consecutive digits OR one "not-a-digit"
data = '[10,20]'
out = [int(m[0]) if m[0].isdigit() else m[0] for m in NUMCHR.finditer(data)]
print(out) #['[', 10, ',', 20, ']']
.finditer
(在这种情况下)将 return 连续数字或每次迭代仅 1 个字符。我们只需检查 return 并相应地进行。
使用 str.isdigit 作为分组键并将键为 True 的组转换为整数:
from itertools import groupby
s = "[10,20]"
r = [[str,int][k]("".join(g)) for k,g in groupby(s,key=str.isdigit)]
print(r)
['[', 10, ',', 20, ']']
您还可以使用 functools 中的 reduce
:
from functools import reduce
def fun(x, y):
if isinstance(x[-1], str) and x[-1].isdigit():
x[-1] = x[-1] + y if y.isdigit() else int(x[-1])
else:
x += [y]
return x
reduce(fun, '[10,[20,30]]', [''])[1:]
Out[]: ['[', 10, '[', 20, 30, ']']
另一种方法可能是使用递归:
def fun_recurse(y, x=None):
if x is None:
x = ['']
if len(y) == 1:
return x[1:] + [y]
if isinstance(x[-1], str) and x[-1].isdigit():
x[-1] = x[-1] + y[0] if y[0].isdigit() else int(x[-1])
return fun_recurse(y[1:], x)
else:
return fun_recurse(y[1:], x + [y[0]])
fun_recurse('[10,[20,30]]')
Out[]: ['[', 10, '[', 20, 30, ']']
给定以下字符串:
"[10,20]"
我想在 Python 中使用列表理解创建以下列表:
['[', 10, ',', 20, ']']
是 10 和 20 整数 和列表中的其余元素 字符.
我假设我需要使用类似于 itertools.groupby(iterable, key=None)
提供的东西:
Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each element. If not specified or is None, key defaults to an identity function and returns the element unchanged. Generally, the iterable needs to already be sorted on the same key function.
然而 Python 的 group by returns 具有连续 keys 和 [=26= 的迭代器]组。在我的例子中,键会改变,所以我想我需要一个类似的迭代器,returns 基于 filter 的组。有什么想法吗?
根据该字符是否为数字进行分组。这可以使用 str.isnumeric
函数作为 groupby()
.
key
参数来完成
s = "[10,20]"
g = itertools.groupby(s, key=str.isnumeric)
然后,对于 True
组,将其转换为整数。离开 False
个组 as-is。
由于 groupby
的值是迭代器,其中每个元素都是一个单独的字符,因此您需要将其与 ""
连接以将其转换为单个字符串,并可选择将该字符串转换为整数。
lst = [int("".join(chars)) if is_numeric else "".join(chars) for is_numeric, chars in g]
给出:
['[', 10, ',', 20, ']']
一行:
lst = [ int("".join(chars))
if is_numeric else "".join(chars)
for is_numeric, chars in itertools.groupby(s, key=str.isnumeric)
]
这也可以使用正则表达式轻松完成。
import re
NUMCHR = re.compile(r'\d+|[^\d]') #consecutive digits OR one "not-a-digit"
data = '[10,20]'
out = [int(m[0]) if m[0].isdigit() else m[0] for m in NUMCHR.finditer(data)]
print(out) #['[', 10, ',', 20, ']']
.finditer
(在这种情况下)将 return 连续数字或每次迭代仅 1 个字符。我们只需检查 return 并相应地进行。
使用 str.isdigit 作为分组键并将键为 True 的组转换为整数:
from itertools import groupby
s = "[10,20]"
r = [[str,int][k]("".join(g)) for k,g in groupby(s,key=str.isdigit)]
print(r)
['[', 10, ',', 20, ']']
您还可以使用 functools 中的 reduce
:
from functools import reduce
def fun(x, y):
if isinstance(x[-1], str) and x[-1].isdigit():
x[-1] = x[-1] + y if y.isdigit() else int(x[-1])
else:
x += [y]
return x
reduce(fun, '[10,[20,30]]', [''])[1:]
Out[]: ['[', 10, '[', 20, 30, ']']
另一种方法可能是使用递归:
def fun_recurse(y, x=None):
if x is None:
x = ['']
if len(y) == 1:
return x[1:] + [y]
if isinstance(x[-1], str) and x[-1].isdigit():
x[-1] = x[-1] + y[0] if y[0].isdigit() else int(x[-1])
return fun_recurse(y[1:], x)
else:
return fun_recurse(y[1:], x + [y[0]])
fun_recurse('[10,[20,30]]')
Out[]: ['[', 10, '[', 20, 30, ']']