我正在尝试使用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:]
,但我不知道我能把它放在哪里。
我是一名业余爱好者,我一直试图弄清楚这个问题。
答案 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+*'
我们需要找到一种方法
我们可以使用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结果,这将是一个字符串。希望这将来会有用!