4

我正在尝试使用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:],但我不知道我可以把它放在哪里。

我是一个业余爱好者,我一直试图弄清楚这个问题很长一段时间。

4

5 回答 5

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. 将它们留在字符串的末尾。

我们可以使用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关键字。

于 2012-11-01T01:24:33.677 回答
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 之间变化。

于 2012-11-01T00:57:35.410 回答
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]

这输出:

>>> 展开('*+123456')
'1*2+3*4+5*6'
>>> 展开('++123')
'1+2+3'
>>> 展开('+*1234')
'1+2*3+4'
于 2012-11-01T01:04:10.707 回答
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(您可以使用模数来实现相同的效果)。有关执行此操作的更多“pythonic”方式,请参阅其他答案(我是为了业余清晰)。

于 2012-11-01T01:01:55.867 回答
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 结果,这将是一个字符串。希望这对将来有用!

于 2012-11-01T01:34:47.383 回答