从列表中取消反向数字

Cancel reverse numbers from a list

假设我根据一些标准列出了正整数,如下所示:

N = 100
List_1 = range(12, N, 1)

# Cancelling multiples of 10
List_2 = [x for x in List_1 if x%10]

# Cancelling palindromic numbers
List_3 = [x for x in List_2 if str(x)!=str(x)[::-1]]

因此,我最后得到的列表(List_3)是:

[12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 31, 32, 34, 35, 36, 37, 38, 39, 41, 42, 43, 45, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 59, 61, 62, 63, 64, 65, 67, 68, 69, 71, 72, 73, 74, 75, 76, 78, 79, 81, 82, 83, 84, 85, 86, 87, 89, 91, 92, 93, 94, 95, 96, 97, 98]

现在,我想从此列表中取消 所有 个数字,这些数字是 reverses of previous[=46] =] 列表中的数字,例如:

取消 21,因为 21 与之前列表中的 12 相反。

取消 31,因为 31 与之前列表中的 13 相反。

等...

取消 98,因为 98 与之前列表中的 89 相反。

所以最后,列表应该减少到 (List_4):

[12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 34, 35, 36, 37, 38, 39, 45, 46, 47, 48, 49, 56, 57, 58, 59, 67, 68, 69, 78, 79, 89]

除了在列表上循环测试数字是否与前一个数字相反之外,我没有找到正确执行此操作的方法,这不是很有效。想以更“Pythonic”的方式获得此 List_4 吗?

一种看待这个问题的方法是,你反转的任何元素 (13->31) 都会在列表中有一个位置,你只想保留那些有较低的指数:

List_4 = [x for x in List_3 if List_3.index(x) < List_3.index(int(str(x)[::-1]))]

大致翻译为:

For each element in the list, take it unless you find its reversed somewhere earlier in the list.

其他可能更好的变化,只保留较小的数字:

List_4 = [x for x in List_3 if x < int(str(x)[::-1])]

结果

[12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 34, 35, 36, 37, 38, 39, 45, 46, 47, 48, 49, 56, 57, 58, 59, 67, 68, 69, 78, 79, 89]

其他注意事项

还有另一种生成 List_4 的方法:

List_4 = [10*x+y for x in range(1,10) for y in range(x+1,10)]

Thanks to wjandrea pulling me out of strings

您可以通过添加一些if条件来获得单循环的列表。

res = []
for n in range(12, N):
    r = int(str(n)[::-1])
    if n not in res and r not in res and n != r and n%10:
        res.append(n)
print(res)

输出:

[12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 34, 35, 36, 37, 38, 39, 45, 46, 47, 48, 49, 56, 57, 58, 59, 67, 68, 69, 78, 79, 89]

像这样:

N = 100
List_1 = range(12, N, 1)

# Cancelling multiples of 10
List_2 = [x for x in List_1 if x%10]

# Cancelling palindromic numbers
List_3 = [x for x in List_2 if str(x)!=str(x)[::-1]]

list_4 = []
for n in List_3:
    if int(str(n)[::-1]) not in list_4:
        list_4.append(n)

Python 式且有效

List_4 = list({min(x, int(str(x)[::-1])) for x in List_3})

解释一下

我们将任何数字 x 映射到 min(x, int(str(x)[::-1]),这是数字与其倒数之间较小的一个。因此 12 和 21 都映射到 12。我们将映射的数字构造为一个集合,这样重复的数字就被取消了。最后我们将集合转换回列表。

有效,因为我们只需要对原始列表进行一次扫描。

为了提高效率,可以在 单次传递 中构建(和过滤)结果列表。

过滤器:

  • 不能被 10 整除
  • 非回文
  • 回文形式尚不存在

示例:

N = 100
l = []
for i in range(12, N):
    p = str(i)[::-1]
    if all([i % 10, 
            str(i) != p,
            int(p) not in l]):
        l.append(i)

输出:

[12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 
 26, 27, 28, 29, 34, 35, 36, 37, 38, 39, 45, 
 46, 47, 48, 49, 56, 57, 58, 59, 67, 68, 69, 
 78, 79, 89]

也许是这样的:

>>> List_4 = list(map(str, List_3))
>>> [List_4.remove(i[::-1]) for i in List_4 if i[::-1] in List_4]
>>> List_4
[12, 13, 14, 15, 16, 17, 18, 19, 23, 24, 25, 26, 27, 28, 29, 34, 35, 36, 37, 38, 39, 45, 46, 47, 48, 49, 56, 57, 58, 59, 67, 68, 69, 78, 79, 89]
>>>