从列表中取消反向数字
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]
>>>
假设我根据一些标准列出了正整数,如下所示:
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 ofstrings
您可以通过添加一些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]
>>>