问题描述
假设我根据某些标准制作了一个正整数列表,如下面的几行所示:
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]
现在,我想从该列表中取消所有与列表中先前数字反转的数字,例如:
取消21
,因为21
与之前在列表中的12
相反。
取消31
,因为31
与之前在列表中的13
相反。
等等...
取消98
,因为98
与之前在列表中的89
相反。
所以最后,列表应该减少到 (List_4
):
[12,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]))]
大致翻译为:
对于列表中的每个元素,除非您在列表的前面某处发现它被反转了,否则采用它。
其他可能更好的变体,只保留较小的数字:
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)]
感谢wjandrea
把我从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,89]
,
Pythonic 且有效
List_4 = list({min(x,int(str(x)[::-1])) for x in List_3})
解释
我们将任何数字 x
映射到 min(x,int(str(x)[::-1])
,它是数字与其相反数之间较小的一个。因此 12 和 21 都映射到 12。我们将映射的数字构造成一个集合,这样重复的数字就被取消了。最后,我们将集合转换回列表。
对于我们只需要对原始列表进行一次扫描是有效的。
,像这样:
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)
,
为了提高效率,可以在单次传递中构建(和过滤)结果列表。
过滤器:
- 不能被 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,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,89]
>>>