Python 如何检查序列是否可以转换为回文
我必须找出列表是否可以是回文。我的程序的第一部分对列表进行排序Python 如何检查序列是否可以转换为回文,python,sorting,python-3.x,palindrome,Python,Sorting,Python 3.x,Palindrome,我必须找出列表是否可以是回文。我的程序的第一部分对列表进行排序 A = [0, 99, 97, 97, 99, 100, 100, 0] # sorted: B = [0, 0, 97, 97, 99, 99, 100, 100] 此列表可以是回文,因为它可以重新排序为: [0, 97, 99, 100, 100, 99, 97, 0] 我编写了以下代码,以在列表可以是回文时返回True i=0 counter = 0 while i<len(B): if i+1 <
A = [0, 99, 97, 97, 99, 100, 100, 0]
# sorted:
B = [0, 0, 97, 97, 99, 99, 100, 100]
此列表可以是回文,因为它可以重新排序为:
[0, 97, 99, 100, 100, 99, 97, 0]
我编写了以下代码,以在列表可以是回文时返回True
i=0
counter = 0
while i<len(B):
if i+1 < len(B):
if B[i]==B[i+1]:
print(B[i],B[i+1])
i+=2
else:
i+=1
counter += 1
else:
i+=1
if counter<2:
return True
return False
i=0
计数器=0
如果数字也需要按顺序排列(如[1,1,2,2,3]
可以工作,但不是[1,1,2,3,3]
),这里有一个简单的方法,它只需要按每2个字符分割排序的列表
def palindrome( input ):
B = sorted(input)
#Get every even index
firstPart = B[::2]
#Get every odd index
secondPart = B[1::2]
#Fix for if there's an odd number of indexes
if len(secondPart) < len(firstPart):
secondPart.append( B[-1] )
#Return true or false
return firstPart==secondPart
print palindrome( [0, 99, 97, 97, 99, 100, 0] )
#True
print palindrome( [0, 99, 97, 97, 99, 100, 100, 0] )
#True
print palindrome( [0, 94, 97, 97, 99, 100, 0] )
#False
计算每个值的出现次数。然后检查奇数计数的数量是否为零或一。没有必要对列表进行排序。这将适用于任何值列表
from collections import Counter
def can_be_palindrome(data):
odd = (c % 2 for c in Counter(data).values())
any(odd) # skip first odd, if present at all
return not any(odd) # ensure no more odds
print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0])) # only even counts, true
print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0, 1])) # one odd count, true
print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0, 1, 2])) # two odd counts, false
print(can_be_palindrome('abcabcd')) # true
print(can_be_palindrome(['a', 'b', 'a', 1, 1]) # true
当我们遍历B
时,我们可以使用集合来跟踪到目前为止哪些元素具有奇数(在这里使用集合比使用列表快得多):
然后,如果赔率的长度为0或1,则打印True
。否则打印False
print len(odds) <= 1 # prints the value you're looking for
print len(赔率)一个快速的(或者我认为是这样):使用字典来计算odd
值。将值存储为字典中的键,如果键出现奇数次,则值为True
,如果键出现偶数次,则值为False
。最后返回True,即.values()
只有0或1个True
元素(也就是说,只有0或1个元素出现奇数次)
迭代器以短路方式工作。第一个any
在满足第一个True
时将返回True
,否则它将扫描整个迭代器。然后我们重新运行any(odd_iter)
——如果迭代器生成另一个True(也称奇数值),则返回True
。如果第一个any
耗尽迭代器,那么第二个any
将直接返回False
。最后,我们求反这个返回值,并从函数返回它
def check_palindrome_sequence(sequence):
odds = {}
for i in sequence:
try:
odds[i] ^= True
except KeyError:
odds[i] = True
odd_iter = iter(odds.values())
any(odd_iter)
return not any(odd_iter)
A = [0, 99, 97, 97, 99, 100, 100, 0]
print(check_palindrome_sequence(A)) # True
A = [0, 99, 97, 97, 99, 100, 100, 0, 1]
print(check_palindrome_sequence(A)) # True
A = [0, 99, 97, 97, 99, 100, 100, 0, 1, 2]
print(check_palindrome_sequence(A)) # False
Python 2.7上的计时:
In [1]: %timeit antti(ls)
1 loops, best of 3: 128 ms per loop
In [2]: %timeit davidism(ls)
10 loops, best of 3: 103 ms per loop
In [3]: %timeit leek(ls)
10 loops, best of 3: 42.1 ms per loop
所有3项的数据都是相同的:
ls = list(range(100000))
ls *= 2
ls += [ 1, 2 ]
random.shuffle(ls)
在Python3上计时,数据同样相同:
In [1]: %timeit leek(ls)
10 loops, best of 3: 37.4 ms per loop
In [2]: %timeit antti(ls)
10 loops, best of 3: 89.3 ms per loop
In [3]: %timeit davidism(ls)
10 loops, best of 3: 52 ms per loop
韭菜的是最好的完全随机整体。nettux的答案是二次减速,100000*2+2元素需要一分钟,我没有耐心计时
对于回文的小值来说,韭菜几乎是赢家
In [1]: %timeit leek(ls)
100000 loops, best of 3: 2.21 µs per loop
In [2]: %timeit antti(ls)
100000 loops, best of 3: 5.52 µs per loop
In [3]: %timeit davidism(ls)
100000 loops, best of 3: 7.45 µs per loop
在python中检查回文可以通过使用l==l[::-1]
来完成。在i+1
行中缺少一个“=”。应该是i+=1
@g.d.d.c假设我的列表如示例中所示,因此我不能反向,但我需要检查数字是否成对或成对+1额外元素计数元素出现的数量。如果有一个元素出现奇数次,其余元素出现偶数次,或者每个元素出现偶数次,那么您的列表可以重新排序以形成回文,只有在元素奇数的情况下,中心元素是最大的回文才适用。请尝试[1,1,2,3,3]为什么?如果重新排序,它可能会形成回文:[1,3,2,3,1]哦,我现在明白了啊哈,我想它必须按顺序排列:)你介意添加一个编辑吗?这可能会导致一些混乱。这对偶数序列非常有效,但如果中心确实不是最大的元素,则对奇数序列无效。@Leekai在天空中再进行一次优化,您可以执行remove=赔率。remove
和add=赔率。add
以挤出更多性能。啊,我使用的是Python 2.7.9,这就解释了区别。谢谢
ls = list(range(100000))
ls *= 2
ls += [ 1, 2 ]
random.shuffle(ls)
In [1]: %timeit leek(ls)
10 loops, best of 3: 37.4 ms per loop
In [2]: %timeit antti(ls)
10 loops, best of 3: 89.3 ms per loop
In [3]: %timeit davidism(ls)
10 loops, best of 3: 52 ms per loop
In [1]: %timeit leek(ls)
100000 loops, best of 3: 2.21 µs per loop
In [2]: %timeit antti(ls)
100000 loops, best of 3: 5.52 µs per loop
In [3]: %timeit davidism(ls)
100000 loops, best of 3: 7.45 µs per loop