使用for循环在python中执行此操作

时间:2012-11-01 00:33:57

标签: python

我正在尝试使用for循环来制定这个:

  • expand('*+123456')应该返回'1*2+3*4+5*6'

  • expand('++123')应该返回'1+2+3'

  • expand('+*1234')应该返回'1+2*3+4'

以交替的方式从给定字符串的前两个字符中选择一个符号,并将其放在前面的数字之间。

以下是我一直在使用的内容:

def expand(original):
    var = ""
    symbols = original[0:2]
    for i in range(len(original)):
        var = var + symbols + original[i]
    return var

我意识到还必须有一个original[2:],但我不知道我能把它放在哪里。

我是一名业余爱好者,我一直试图弄清楚这个问题。

5 个答案:

答案 0 :(得分:4)

是的,通过在其中添加[2:]可以改善您的功能,但也可能会失去range(len(original))。每当你发现自己写range(len(something))时,你应该退一步思考你实际上要做的事情。

在这种情况下,您正在查找字符串中的字符,您可以使用for x in string更直接地获取字符。这是一个稍微改进的版本,将这些想法考虑在内:

def expand(original):
    var = ""
    symbols = original[:2]
    for digit in original[2:]:
        var += (digit + symbols)
    return var

这会阻止你在输出的开头得到奇怪的符号混合,但它仍然不完美:

>>> expand('+*1234')
'1+*2+*3+*4+*'

我们需要找到一种方法

  1. 交替取符号,
  2. 将它们从字符串的末尾移开。
  3. 我们可以使用itertools.cycle处理第一个问题,并使用第二个字符串切片:

    from itertools import cycle
    
    def expand(original):
        var = ""
        symbols = cycle(original[:2])
        for digit in original[2:]:
            var += (digit + next(symbols))
        return var[:-1]
    

    这样可行,但在某些时候,有人会告诉你不应该使用++=来构建字符串,因为它效率低下。如果我们构建一个列表,然后使用str.join()将其转换为字符串,我们可以稍微改进一下:

    from itertools import cycle
    
    def expand(original):
        chars = []
        symbols = cycle(original[:2])
        for digit in original[2:]:
            chars.extend([digit, next(symbols)])
        return "".join(chars[:-1])
    

    然而,我们可以做得更好。我们不必每次都致电next(symbols),而是可以使用zip()一次获取下一个符号和下一个数字:

    from itertools import cycle
    
    def expand(original):
        chars = []
        for symbol, digit in zip(cycle(original[:2]), original[2:]):
            chars.extend([digit, symbol])
        return "".join(chars[:-1])
    

    ......那可能就够了: - )

    编辑:因为在对另一个答案的评论中,你已经说过你不允许从标准库导入任何东西(一个相当愚蠢的限制IMO,但它就是这样),你可以使用本答案前面链接中描述的cycle()的Python实现:

    def cycle(iterable):
        # cycle('ABCD') --> A B C D A B C D A B C D ...
        saved = []
        for element in iterable:
            yield element
            saved.append(element)
        while saved:
            for element in saved:
                yield element
    

    ...但您可能必须准备好让老师相信您理解它,这意味着您需要了解yield关键字。

答案 1 :(得分:3)

您可以尝试以下方式:

a = "*+123456"

def expand(input):
    symbols = input[:2]
    numbers = input[2:]

    result = ""
    for count, number in enumerate(numbers):
        # Switch symbol for every other iteration
        result += number + symbols[count%2]

    # There's an extra symbol at the end, so remove it.
    return result[:-1]

以下是解释器中的示例运行:

>>> a = "*+123456"
>>> def expand(input):
...     symbols = input[:2]
...     numbers = input[2:]
...     result = ""
...     for count, number in enumerate(numbers):
...         result += number + symbols[count%2]
...     return result[:-1]
... 
>>> expand(a)
'1*2+3*4+5*6'
>>> a = "++123456"
>>> expand(a)
'1+2+3+4+5+6'

代码中需要注意的事项:

enumerate - 获取一个可迭代对象,并以(index, value)形式返回一个元组。

input[:2] - 从一开始就将一个字符数组切换到位置2的元素(不包括在内)

input[2:] - 从位置2到结束(包括)

获取一个字符数组

list[:-1] - 从列表的开头到列表末尾的1个元素。

count%2 - 获取数组中字符的计数(索引)并将其除以2,保留余数。每个步骤在两个符号之间切换时,结果将在0和1之间变化。

答案 2 :(得分:2)

您可以使用itertools“循环”操作符号,然后将它们与数字交错(“zip”):

import itertools

def expand(original):
    var = ""
    symbols = original[:2]
    numbers = original[2:]
    for symbol, number in zip(numbers[:-1], itertools.cycle(symbols)):
        var += symbol + number
    return var + numbers[-1]

输出:

>>> expand('*+123456')
'1*2+3*4+5*6'
>>> expand('++123')
'1+2+3'
>>> expand('+*1234')
'1+2*3+4'

答案 3 :(得分:1)

这是一个使用FOR循环的选项:

def expand(x):

    p=x[:2]
    n=x[2:]
    s=''
    c=0

    for i in n:
       s+=i
       s+=p[c]
       c=1-c

    return s[:-1]

我们的想法是将您的字符串分隔为运算符字符串 p 和数字字符串 n ,然后迭代两者。 c 变量从0变为1并返回,因此它会不断迭代 p (您可以使用modulo实现相同)。对于更多“pythonic”方式,请参阅其他答案(我的目标是业余清晰度)。

答案 4 :(得分:1)

迟到的回答,这里的每一个都更有用,但出于某种原因,这引起了我的兴趣:

In [9]: from itertools import izip, cycle

In [10]: def expand(s):
   ....:   return ''.join(reduce(lambda x, y: x+y, izip(s[2:], cycle(s[:2]))))[:-1]
   ....:

In [11]: expand('*-123')
Out[11]: '1*2-3'

In [12]: expand('+-123456')
Out[12]: '1+2-3+4-5+6'

我完全赞同@Bitwise等人所说的 - 绝对不是你所追求的,因为它不符合你的约束,所以道歉让流混乱:)

为了后人,这将获取有问题的字符串,然后使用reduce函数将数字与其中一个交替符号字符串配对。然后我们修剪最终符号并返回join'ed结果,这将是一个字符串。希望这将来会有用!