神秘的 python 行为
Mysterious python behaviour
我正在尝试编写一个快速脚本来输出一个序列。
序列开始如下:
1,11,21,1211,111221,312211...
以 1 开头,然后 1 1 第二项是 11,因为两个 1 第三项是 21 等。
我在下面写了一个脚本,它输出这个序列中的术语。
当 input_string 为 1(即 11)时,它会输出正确的下一项。但是之后的所有项也都输出为 11..... 如果我手动将输入设置为 11,则所有项都会正确计算。
这没有任何意义,因为初始输入 "1"
我的 total_sequence[0]
变量将是 "1"
,给出 "11"
的正确输出。
下一项将 total_sequence[1]
作为其输入,即 "11"
即最后一次迭代输出。
但这给出了 "11"
作为它的输出。
如果我直接将 "11"
作为 total_sequence[1] 术语而不是引用 total_sequence[1]
(which = "11"
),那么就会给出正确的输出。
所以基本上为什么 input_string = "11"
与 output[1]
不同 output = ["1","11"]
?
input_string= "1"
N=5
total_sequence = [input_string]
for i in xrange(0,N,1):
N_counter = int(0)
previous_char = ""
output_string = ""
character_index = int(1)
#loop through each character in the current sequence term
for current_char in total_sequence[i]:
#if first character
if character_index == 1:
N_counter = 1
#if last character
if character_index == len(input_string):
if current_char == previous_char:
N_counter = N_counter + 1
if current_char != previous_char:
if previous_char!="":
output_string = output_string + str( N_counter ) + str( previous_char )
N_counter = int( 1 )
output_string = output_string + str( N_counter ) + str( current_char )
#if neither first nor last character
if character_index != 1 and character_index != len(input_string) :
if current_char == previous_char:
N_counter = N_counter + 1
if current_char != previous_char:
output_string = output_string + str( N_counter ) + str( previous_char )
N_counter = int( 1 )
character_index = character_index + 1
previous_char = current_char
total_sequence.append( output_string)
print total_sequence
您在循环主体中使用了 input_string
,但这从未改变,它始终是第一个字符串,在您的示例中 "1"
.
可能将内循环的第一行更改为:
input_string = total_sequence[i]
for current_char in input_string:
应该够用了,我没测试
这被称为 "look and say" 序列;使用 itertools.groupby
:
可以更简单地实现它
from itertools import groupby
def look_and_say(n):
"""
Generate the first `n` terms of the sequence
'1', '11', '21', '1211', ...
"""
if n < 1:
return
# first term
term = "1"
yield term
# second through `n`th terms
for term_num in range(1, n):
chars = []
for ch,reps in groupby(term):
count = len(list(reps))
chars.append(str(count))
chars.append(ch)
term = "".join(chars)
yield term
然后
N = 5
print(list(look_and_say(N)))
给予
['1', '11', '21', '1211', '111221']
有趣的奖励:证明该序列永远不会包含大于 3 的数字。
我正在尝试编写一个快速脚本来输出一个序列。 序列开始如下: 1,11,21,1211,111221,312211... 以 1 开头,然后 1 1 第二项是 11,因为两个 1 第三项是 21 等。
我在下面写了一个脚本,它输出这个序列中的术语。 当 input_string 为 1(即 11)时,它会输出正确的下一项。但是之后的所有项也都输出为 11..... 如果我手动将输入设置为 11,则所有项都会正确计算。
这没有任何意义,因为初始输入 "1"
我的 total_sequence[0]
变量将是 "1"
,给出 "11"
的正确输出。
下一项将 total_sequence[1]
作为其输入,即 "11"
即最后一次迭代输出。
但这给出了 "11"
作为它的输出。
如果我直接将 "11"
作为 total_sequence[1] 术语而不是引用 total_sequence[1]
(which = "11"
),那么就会给出正确的输出。
所以基本上为什么 input_string = "11"
与 output[1]
不同 output = ["1","11"]
?
input_string= "1"
N=5
total_sequence = [input_string]
for i in xrange(0,N,1):
N_counter = int(0)
previous_char = ""
output_string = ""
character_index = int(1)
#loop through each character in the current sequence term
for current_char in total_sequence[i]:
#if first character
if character_index == 1:
N_counter = 1
#if last character
if character_index == len(input_string):
if current_char == previous_char:
N_counter = N_counter + 1
if current_char != previous_char:
if previous_char!="":
output_string = output_string + str( N_counter ) + str( previous_char )
N_counter = int( 1 )
output_string = output_string + str( N_counter ) + str( current_char )
#if neither first nor last character
if character_index != 1 and character_index != len(input_string) :
if current_char == previous_char:
N_counter = N_counter + 1
if current_char != previous_char:
output_string = output_string + str( N_counter ) + str( previous_char )
N_counter = int( 1 )
character_index = character_index + 1
previous_char = current_char
total_sequence.append( output_string)
print total_sequence
您在循环主体中使用了 input_string
,但这从未改变,它始终是第一个字符串,在您的示例中 "1"
.
可能将内循环的第一行更改为:
input_string = total_sequence[i]
for current_char in input_string:
应该够用了,我没测试
这被称为 "look and say" 序列;使用 itertools.groupby
:
from itertools import groupby
def look_and_say(n):
"""
Generate the first `n` terms of the sequence
'1', '11', '21', '1211', ...
"""
if n < 1:
return
# first term
term = "1"
yield term
# second through `n`th terms
for term_num in range(1, n):
chars = []
for ch,reps in groupby(term):
count = len(list(reps))
chars.append(str(count))
chars.append(ch)
term = "".join(chars)
yield term
然后
N = 5
print(list(look_and_say(N)))
给予
['1', '11', '21', '1211', '111221']
有趣的奖励:证明该序列永远不会包含大于 3 的数字。