简体   繁体   English

如何将列表中的数字部分分组在一起

[英]How to group a section of numbers in a list together Python

I am currently working on a program in which I must take a string as input and then reverse all of the numbers in that string, leaving all other characters the same. 我目前正在开发一个程序,其中我必须将字符串作为输入,然后反转该字符串中的所有数字,而使所有其他字符保持不变。 I managed to do this, however it seems that I must reverse sections of numbers at a time, and not reverse every number. 我设法做到了,但是似乎我必须一次反转数字的各个部分,而不是反转每个数字。 I am not sure how I can do this with my solution. 我不确定如何用我的解决方案来做到这一点。 I would prefer not to use any libraries. 我宁愿不使用任何库。

For example: 例如:

For input abc123abc456abc7891 用于输入abc123abc456abc7891

My result: abc198abc765abc4321 我的结果:abc198abc765abc4321

Target Result: abc321abc654abc1987 目标结果:abc321abc654abc1987

Here is what I have: 这是我所拥有的:

#Fucntion just reverses the numbers that getn gives to it
def reverse(t):
    t = t[::-1]
    return t

def getn(w):
    w = list(w)
    Li = []
#Going through each character of w(the inputted string) and adding any numbers to the list Li
    for i in w:
        if i.isdigit():
            Li.append(i)
#Turn Li back into a string so I can then reverse it using the above function
#after reversing, I turn it back into a list
    Li = ''.join(Li)
    Li = reverse(Li)
    Li = list(Li)
#I use t only for the purpose of the for loop below,
#to get the len of the string,
#a is used to increment the position in Li
    t = ''.join(w)
    a = 0
#This goes through each position of the string again,
#and replaces each of the original numbers with the reversed sequence
    for i in range(0,len(t)):
        if w[i].isdigit():
            w[i] = Li[a]
            a+=1
#Turn w back into a string to print
    w = ''.join(w)
    print('New String:\n'+w)

x = input('Enter String:\n')
getn(x)

The following isn't particularly elegant, but is conceptually fairly simple, using groupby from itertools to split the string up into the groups of digits or non-digits (this is Python 3.7, I think it should work on any Python 3.x but haven't tested except on 3.7): 以下内容并不是特别优雅,但从概念上讲相当简单,使用itertools groupby将字符串分成数字或非数字组(这是Python 3.7,我认为它应可在任何Python 3.x上使用,但除3.7之外未测试):

from itertools import groupby

def getn(s):
    sections = groupby(s, key=lambda char: char.isdigit())
    result = []
    for isdig, chars in sections:
        if isdig:
            result += list(reversed(list(chars)))
        else:
            result += list(chars)
    return "".join(result)

input = "abc123abc456abc7891"
print(getn(input))

Solution outline: 解决方案概述:

  • Break the string into a list of substrings. 将字符串分成子字符串列表。 Each substring is defined by the division between digits and non-digits. 每个子字符串由数字和非数字之间的分界来定义。 Your result at othe end of this stage should be ["abc", "123", "abc", "456", "abc", "7891"] 在此阶段结束时,您的结果应为["abc", "123", "abc", "456", "abc", "7891"]
  • Go through this list; 浏览此列表; replace each digit string with its reverse. 将每个数字字符串替换为反向。
  • join this list into a single string. join该列表合并成一个字符串。

The final step is simply ''.join(substring_list) . 最后一步就是''.join(substring_list)

The middle step is contained in what you're already doing. 中间步骤包含在您已经在做的事情中。

The first step isn't trivial, but well within the coding ability in your original post. 第一步并非易事,但要在原始帖子的编码能力范围内。

Can you take it from here? 你能从这里拿走吗?


UPDATE 更新

Here's the logic to break the string into groups as needed. 这是根据需要将字符串分成几组的逻辑。 Check the "digit-ness" of each char. 检查每个字符的“位数”。 If it's different from that of the previous char, then you have to start a new substring. 如果它与以前的字符不同,则必须开始一个新的子字符串。

instr = "abc123abc456abc7891"

substr = ""
sub_list = []
prev_digit = instr[0].isdigit()

for char in instr:
    # if the character's digit-ness is different from the last one,
    #    then "tie off" the current substring and start a new one.
    this_digit = char.isdigit()
    if this_digit != prev_digit:
        sub_list.append(substr)
        substr = ""
        prev_digit = this_digit

    substr += char

# Add the last substr to the list
sub_list.append(substr)

print(sub_list)

Output: 输出:

['abc', '123', 'abc', '456', 'abc', '7891']

This is a working code based on @prune suggestion. 这是一个基于@prune建议的工作代码。

def type_changed(s1,s2):
    if s1.isdigit() != s2.isdigit():
        return True

def get_subs(s):
    sub_strings = list()
    i = 0
    start = i
    while i < len(s):
        if i == len(s)-1:
            sub_strings.append(s[start:i+1])
            break
        if type_changed(s[i], s[i+1]):
            sub_strings.append(s[start:i+1])
            start = i+1
        i +=1
    return sub_strings

def reverse(subs):
    for i, sub in enumerate(subs):
        if sub.isdigit():
            subs[i] = subs[i][::-1]
    return ''.join(subs)


test_strings = [
    'abc123abc456abc7891b',
    'abc123abc456abc7891',
    'abc123abc456abc7891abc',
    'a1b2c3d4e5f6',
    'a1b2c3d4e5f6g',
    '1234',
    'abcd',
    '1',
    'a'
]

for item in test_strings:
    print(item)
    print(reverse(get_subs(item)))
    print

Idea is to separate numbers and letters into substring sections. 想法是将数字和字母分成子字符串部分。 Iterate through each section and reverse only the integer sections. 遍历每个部分,仅反转整数部分。 Then join the sections into a single string. 然后将这些部分连接到一个字符串中。

def getn(w):
   ans = []
   section = ''

   if w[0].isdigit():
       last = 'digit'
   else:
       last = 'letter'

   for char in w:
       if char.isdigit():
           if last == 'letter':
               ans.append(section)
               section = ''
               last = 'digit'
           section += char
       else:
           if last == 'digit':
               ans.append(section)
               section = ''
               last = 'letter'
           section += char
   ans.append(section)

   for index, section in enumerate(ans):
       if section.isdigit():
           ans[index] = section[::-1]
   return ''.join(ans)

string = 'abc123abc456abc7891'
print(getn(string))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM