90

I'm trying to make a program which checks if a word is a palindrome and I've gotten so far and it works with words that have an even amount of numbers. I know how to make it do something if the amount of letters is odd but I just don't know how to find out if a number is odd. Is there any simple way to find if a number is odd or even?

Just for reference, this is my code:

a = 0

while a == 0:
    print("\n \n" * 100)
    print("Please enter a word to check if it is a palindrome: ")
    word = input("?: ")

    wordLength = int(len(word))
    finalWordLength = int(wordLength / 2)
    firstHalf = word[:finalWordLength]
    secondHalf = word[finalWordLength + 1:]
    secondHalf = secondHalf[::-1]
    print(firstHalf)
    print(secondHalf)

    if firstHalf == secondHalf:
        print("This is a palindrom")
    else:
        print("This is not a palindrom")


    print("Press enter to restart")
    input()
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
user3320350
  • 1,085
  • 1
  • 7
  • 4
  • 1
    I don't know how you'd express this in Python, but (wordlength mod 2)== 1 will be true if a word has an odd number of characters. –  Feb 17 '14 at 19:05

6 Answers6

210
if num % 2 == 0:
    pass # Even 
else:
    pass # Odd

The % sign is like division only it checks for the remainder, so if the number divided by 2 has a remainder of 0 it's even otherwise odd.

Or reverse them for a little speed improvement, since any number above 0 is also considered "True" you can skip needing to do any equality check:

if num % 2:
    pass # Odd
else:
    pass # Even 
DeadChex
  • 4,379
  • 1
  • 27
  • 34
84

Similarly to other languages, the fastest "modulo 2" (odd/even) operation is done using the bitwise and operator:

if x & 1:
    return 'odd'
else:
    return 'even'

Using Bitwise AND operator

  • The idea is to check whether the last bit of the number is set or not. If last bit is set then the number is odd, otherwise even.
  • If a number is odd & (bitwise AND) of the Number by 1 will be 1, because the last bit would already be set. Otherwise it will give 0 as output.
Daniel Selvan
  • 959
  • 10
  • 23
lejlot
  • 64,777
  • 8
  • 131
  • 164
  • 27
    "Explicit is better than implicit. ; Simple is better than complex.", from The Zen of Python – Maxime Lorant Feb 17 '14 at 19:13
  • 6
    Because `num % 2` is more explicit than `num & 1`? Python doesn't have a builtin `odd()` function, so you're not going to get more explicit than this unless you write your own, in which case it still doesn't matter which method you use to implement it. – Yay295 Nov 17 '18 at 14:53
  • 8
    I think @MaximeLorant refers to the fac that the bitwise and operation is a kind of obscure way to do this, although the fastes. If you are not going for speed, the modulo operation is the clearest way to do it. – Puff Nov 28 '18 at 03:19
  • 3
    That's right @Puff. The modulo operator is well known for such use cases, while the bitwise operator on numbers is not that common. Plus, both solutions seem to run at the same speed on my PC (using `timeit.timeit('a = random.randint(1, 1000); a & 1', setup='import random', number=1000000)`, I get 1.1109 for bitwise and 1.1267 for modulo...) I still agree with my comment from 2014, hooray :-) – Maxime Lorant Nov 28 '18 at 09:03
  • Actually `timeit` says `x & 1` takes 38 ns while `x % 2` takes 25 ns, so this is slower and (slightly) less readable – endolith May 27 '20 at 03:39
  • 2
    This is interesting as I've tried running this with timeit as well. I believe that since python wraps numbers as objects, the underlying code may not be as optimized for the AND operation. From working with assembly, I know the bitwise AND is faster (by far) than the modulo operation (which uses a divide and picks up the remainder register). This can be tested with other languages. I disagree about being explicit and readable ... but perhaps it's easier for a novice to understand. – codeaperature Aug 17 '20 at 01:37
11

It shouldn't matter if the word has an even or odd amount fo letters:

def is_palindrome(word):
    if word == word[::-1]:
        return True
    else:
        return False
kylieCatt
  • 10,672
  • 5
  • 43
  • 51
  • 11
    Why not just `return word == word[::-1]`? Return True if condition is True and return False if condition is false, is the same as return condition... – Hyperboreus Feb 17 '14 at 19:18
  • 3
    @Hyperboreus Just want to be as explicit as possible since I ahve a feeling that the OP is very new to Python. – kylieCatt Feb 17 '14 at 19:21
  • This one trumps my own kludgy solution in both simplicity and clarity! – Jeff Wright Mar 02 '16 at 13:04
3

One of the simplest ways is to use de modulus operator %. If n % 2 == 0, then your number is even.

Hope it helps,

Esteban Aliverti
  • 6,259
  • 2
  • 19
  • 31
3

Use the modulo operator:

if wordLength % 2 == 0:
    print "wordLength is even"
else:
    print "wordLength is odd"

For your problem, the simplest is to check if the word is equal to its reversed brother. You can do that with word[::-1], which create the list from word by taking every character from the end to the start:

def is_palindrome(word):
    return word == word[::-1]
Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
0

The middle letter of an odd-length word is irrelevant in determining whether the word is a palindrome. Just ignore it.

Hint: all you need is a slight tweak to the following line to make this work for all word lengths:

secondHalf = word[finalWordLength + 1:]

P.S. If you insist on handling the two cases separately, if len(word) % 2: ... would tell you that the word has an odd number of characters.

NPE
  • 486,780
  • 108
  • 951
  • 1,012