我的Python代码只选择列表内容的一半?

时间:2015-04-09 04:12:41

标签: python list insert

我对Python非常陌生,我正在浏览一些我在网上找到的示例项目,但我现在仍然坚持使用我的回文检查器。

现在,我的代码将一个单词作为输入,将其拆分为一半,将每个部分保存到单独的变量中,生成两个变量列表,并从那里它应该反转第二个列表,以便我可以将它与首先,但是从我试图修复它的内容来看,它只是将一半的选择附加到新列表中。

例如,如果我输入" racecar",它会将其拆分为" race"和" ecar"很好,但是当我转向" ecar"它只会让我回来" [' c',' e']"。 (另外,如果我切换变量以反转前半部分,我会得到相同的错误)

我一直试图弄清楚它已经有一段时间了,而且我没有取得任何进展,所以非常感谢一些帮助!

Ninja编辑:如果有更简单的方法(我确信有),我很想知道,但我仍然想弄明白我的意思。在我已经拥有的代码中做错了所以我可以尝试从中学习

到目前为止,这是我的代码:

print "Please enter a word you want to check is a palindrome"
input = raw_input('> ')

#Gets lengths of input
full_length = len(input)
split_length = len(input) / 2

#If word has an even length split like this
if full_length % 2 == 0:
    first_half = input[0: split_length]
    second_half = input[split_length:full_length]

#If word does not have even length split like this
else:
    first_half = input[0:split_length+1]
    second_half = input[split_length:full_length]

#Make both halves lists
first_half_list = list(first_half)
print first_half_list
second_half_list = list(second_half)
print second_half_list

# Reverse second half
rev_second_half = []


for x in second_half_list:
    current_letter = second_half_list[0]
    second_half_list.remove(second_half_list[0])
    rev_second_half.insert(0, current_letter)

print rev_second_half

"""
#Check to see if both lists are identical

#If they are identical
print "This word is a palindrome!"

#If they are not identical
print "This word is not a palindrome."
"""

这是我进入赛车'

时得到的输出
racecar
['r','a','c','e']
['e','c','a','r']
['c', 'e']

3 个答案:

答案 0 :(得分:3)

有很多不必要的工作正在进行中。无需转换为列表;口译员可以为您管理这一切。无需手动反转字符串;使用切片。无需手动声明字符串中第一个和最后一个字符的索引;口译员知道他们在哪里。这是代码的固定版本;你可以view a demo at IDE One

input = 'racecar'

#Gets lengths of input
full_length = len(input)
split_length = len(input) / 2

#If word has an even length split like this
if full_length % 2 == 0:
    first_half = input[:split_length]
    second_half = input[split_length:]

#If word does not have even length split like this
else:
    first_half = input[:split_length+1]
    second_half = input[split_length:]

print first_half
print second_half

rev_second_half = second_half[::-1]

print rev_second_half
  

种族
  ECAR
  种族

通过使用具有负迭代步骤的切片,注意后半部分的反转方式?您可以只对源字符串执行一次,并将结果与​​原始字符串进行比较。现在你有一个单行方法来检查字符串是否是回文:input == input[::-1]

关于切片语法的更多内容(您可能想查看this question)。 input[::-1]input[0:len(input):-1]完全相同。冒号分隔三个参数,即start : end : step。前两个创建了一个范围,其中包含start以及它与end之间的所有内容,但不包括end本身。不指定startend会导致解释器假设您分别表示“使用0”和“使用len”。未指定step会导致假设为1.使用否定步骤意味着“从end开始,然后向后移动step”。

如果要省略参数并指定带切片的范围,则需要包含冒号,因此解释器可以告诉哪些参数被省略。例如,input[-1]将返回输入的最后一个元素,因为没有冒号表示您指定了索引,而负数表示“从末尾向后”,因此print input[:-1]将产生“raceca”,如果你的输入是“赛车”。

至于你的代码出了什么问题,问题出现在你的反向循环中。

for x in second_half_list:
    current_letter = second_half_list[0]
    second_half_list.remove(second_half_list[0])
    rev_second_half.insert(0, current_letter)

您正在从正在迭代的列表中删除项目。不要那样做,这是造成问题的好方法;这就是为什么在这种情况下你只能获得一半的名单。还有不必要的复制,但这不会导致不正确的结果。最后,你根本就没有使用你的迭代变量,这肯定表明你的循环代码存在某种问题。在这里,如果您修复了列表突变但继续使用second_half_list[0],则会在len(second_half_list)次重复该字母。如果你真的需要实际反转列表,你可以这样做:

for x in second_half_list:
    rev_second_half.insert(0, x)

但是如果在迭代期间需要某种副作用,那么你应该只实际迭代列表。对于python的纯粹逆转,你需要这个,它会表现得更好:

rev_second_half = [reversed(second_half_list)]

答案 1 :(得分:0)

要反转字符串(不到位):

rev_second_half = second_half_list[::-1]

扩展: 我建议将这两半保持为字符串,然后你可以将它们与==进行比较,上面的反转技术也适用于字符串。

答案 2 :(得分:0)

您只获得两个值的原因是您在迭代时改变列表 - 您不应该这样做,只是因为它很难理由。举个例子:

In [34]: nums = range(5)  # [0, 1, 2, 3, 4]

In [35]: for num in nums:
   ....:    print "num", num
   ....:    print "nums", nums
   ....:    nums.remove(nums[0])
   ....:
num 0
nums [0, 1, 2, 3, 4]
num 2
nums [1, 2, 3, 4]
num 4
nums [2, 3, 4]

请注意,这只会循环三次。第一次通过,一切都花花公子,但你删除了第一个元素。但是,Python的循环逻辑认为它必须转到第二项 - 但是你删除了第一项!这是指现在的第二项,还是第二项开始的时候?对于Python的内部,它现在意味着第二个项目 - 这是事情开始时的第三个项目(即值2)。从那里,东西只是滚雪球。

这里的教训是在迭代时不要改变列表。只需使用其他方法来逆转这里提到的人们。