如何将字符串中的交替数字和字符分隔成字典或列表?

how to separate alternating digits and characters in string into dict or list?

'L134e2t1C1o1d1e1'

原始字符串是“LeetCode”

但我需要将字符串与数字分开,数字不仅可以是一位数,还可以是 3-4 位数字,例如 345。

我的代码需要分离成键值字典;键是字符,数字是字符后面的数字。还创建 2 个单独的数字列表,仅限字母。

预期输出:

letters = ['L', 'e', 't', 'C', 'o', 'd', 'e']
digits = [134,2,1,1,1,1,1]

此代码未正确处理此问题。

def f(s):

    d = dict()
    letters = list()
    # letters = list(filter(lambda x: not x.isdigit(), s))

    i = 0
    while i < len(s):
        print('----------------------')
        if not s[i].isdigit():

            letters.append(s[i])

        else:
            j = i
            temp = ''
            while j < len(s) and s[j].isdigit():
                j += 1

            substr = s[i:j]
            print(substr)
            
        i += 1

    print('----END -')
    print(letters)

您的字符串只有两个 e's,所以我又添加了一个来完成示例。这是您可以做到的一种方式:

import re

t = 'L1e34e2t1C1o1d1e1'
print(re.sub('[^a-zA-Z]', '', t))

结果:

LeetCode

我知道你不能使用正则表达式,但为了完成这个答案,我将添加一个解决方案:

def f(s):
    d = re.findall('[0-9]+', s)
    l = re.findall('[a-zA-Z]', s)
    print(d)
    print(l)

f(t)

结果:

['134', '2', '1', '1', '1', '1', '1']
['L', 'e', 't', 'C', 'o', 'd', 'e']

通过以下修改,您的函数将 s 中的字母与数字分开:

def f(s):
    letters = list()
    digits = list()
    i = 0
    while i < len(s):
        if not s[i].isdigit():
            letters.append(s[i])
            i += 1
        else:
            j = i
            temp = ''
            while j < len(s) and s[j].isdigit():
                j += 1
            substr = s[i:j]
            i = j
            digits.append(substr)
    print(letters)
    print(digits)
f('L134e2t1C1o1d1e1')

正如我在评论中所说,您在内部循环终止后没有更新 i,这使得 i 返回到之前已经处理过的索引。

你编辑了你的问题,我有点困惑,所以这里有一个非常详尽的代码,给你一个字母列表、数字列表、数字与数字相关联的字典,最后是句子相应的字符数...

def f(s):
    letters = [c for c in s if c.isalpha()]
    numbers = [c for c in s if c.isdigit()]

    mydict = {}
    currentKey = ""
    for c in s:
        print(c)
        if c.isalpha():
            mydict[c] = [] if c not in mydict.keys() else mydict[c]
            currentKey = c
        elif c.isdigit():
            mydict[currentKey].append(c)

    sentence = ""
    for i in range(len(letters)):
        count = int(numbers[i])
        while count > 0:
            sentence += letters[i]
            count -= 1

    print(letters)
    print(numbers)
    print(mydict)
    print(sentence)

如果我被限制为不使用正则表达式,我会按照以下方式进行

text = 'L134e2t1C1o1d1e1'
letters = [i for i in text if i.isalpha()]
digits = ''.join(i if i.isdigit() else ' ' for i in text).split()
print(letters)
print(digits)

输出

['L', 'e', 't', 'C', 'o', 'd', 'e']
['134', '2', '1', '1', '1', '1', '1']

说明:对于字母,我使用带条件的简单列表理解,.isalpha() 是 str 方法,它检查字符串(在此由一个字符组成)是否为字母。对于数字(应该更确切地说是数字),我使用单个 space 替换 non-digits,使用 ''.join 将其转换为字符串,然后使用 .split()(它确实拆分为一个或多个白色spaces)。请注意,digits 现在是 strlist,而不是 int,如果需要,请添加以下行:

digits = list(map(int,digits))
letters = []
digits = []
dig = ""
for letter in 'L134e2t1C1o1d1e1':
    if letter.isalpha():
        # do not add empty string to list
        if dig:
            # append dig to list of digits
            digits.append(dig)
            dig = ""
        letters.append(letter)
        # if it is a actual letter continue
        continue
    # add digits to `dig`
    dig = dig + letter

试试这个。这个想法是跳过所有实际字母并将数字添加到 dig.

我知道有一个可接受的答案,但无论如何我都会抛出这个:

letters = []
digits = []

lc = 'L134e2t1C1o1d1e1'
n = None
for c in lc:
    if c.isalpha():
        if n is not None:
            digits.append(n)
            n = None
        letters.append(c)
    else:
        if n is None:
            n = int(c)
        else:
            n *= 10
            n += int(c)
if n is not None:
    digits.append(n)

for k, v in zip(letters, digits):
    dct.setdefault(k, []).append(v)
print(letters)
print(digits)
print(dct)

输出:

['L', 'e', 't', 'C', 'o', 'd', 'e']
[134, 2, 1, 1, 1, 1, 1]
{'L': [134], 'e': [2, 1], 't': [1], 'C': [1], 'o': [1], 'd': [1]}