3

I want to generate list of all palindromic numbers of 3 digits in python. I can code this in a crude way but is there some intuitive way using list comprehension or itertools etc?

And also, How to do it if it is given the number is k digits instead of just 3?

cigien
  • 57,834
  • 11
  • 73
  • 112
prongs
  • 9,422
  • 21
  • 67
  • 105

3 Answers3

11
>>> L = [int("%d%d%d" % (x,y,x)) for x in range(1,10) for y in range(10)]
>>> L
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252,
 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414,
 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575,
 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737,
 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898,
 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]

UPDATE: To be more memory and speed efficient, you can replace string formatting and int conversion by x+y*10+x*100. Thanks @larsmans.

UPDATE 2: And that's for k digits!

[int(''.join(map(str, (([x]+list(ys)+[z]+list(ys)[::-1]+[x]) if k%2
                  else ([x]+list(ys)+list(ys)[::-1]+[x])))))
            for x in range(1,10)
            for ys in itertools.permutations(range(10), k/2-1)
            for z in (range(10) if k%2 else (None,))]

And that's optimized to NOT use strings!

[sum([n*(10**i) for i,n in enumerate(([x]+list(ys)+[z]+list(ys)[::-1]+[x]) if k%2
                                else ([x]+list(ys)+list(ys)[::-1]+[x]))])
            for x in range(1,10)
            for ys in itertools.permutations(range(10), k/2-1)
            for z in (range(10) if k%2 else (None,))]

I used permutations, and a different loop for the first digit, which cannot be 0, and the last loop is to add all possible digits in the middle if k%2 == 1 (k is odd).

Suggestions to optimize this are welcome!

jadkik94
  • 7,000
  • 2
  • 30
  • 39
2

For the generalisation to k digits, the most obvious way is to do something like:

palindromes = [x for x in itertools.permutations(string.digits, k) if x == x[::-1]]

But it isn't very efficient - it generates every possible 3-digit number, and discards the ones that aren't palindromes. However, it is possible to generalise solutions like @jadkik94's - what you need to do is generate every combination of half the length (rounding down), and stick the mirror of it on the end:

palindromes = [x + x[::-1] for x in permutations(digits, k//2)]

Will work for all even k - for odd k, you add an extra loop to put all of 0-9 in between the mirrored halves.

lvc
  • 34,233
  • 10
  • 73
  • 98
0

The simplest way would be converting the numbers to strings and checking if they are palindromes. To find the palindromes of the "k" number of digits, the list comprehension could be;

palindromes = [num for num in range(pow(10,k-1),pow(10,k)) if str(num) == str(num)[::-1]]
Deepeshkumar
  • 395
  • 3
  • 13