【问题标题】:How to generate a list of numbers where all digits are even?如何生成所有数字都是偶数的数字列表?
【发布时间】:2017-11-06 21:12:42
【问题描述】:

我有一个使用列表推导生成的数字列表,但希望 python 检查输出并仅在数字中的每个数字都是偶数(例如 266)时打印结果。如果数字是偶数,例如 218,但每个数字都不能被 2 整除,则不应打印。有人可以帮忙吗?

这是我的代码:

jail=[res for res in range(200,300)if res % 2 ==0 ]
print(jail)

【问题讨论】:

  • @Bahrom 您的回答值得更好。我没有得到反对票。
  • 这里没有尝试。提示:使用递归函数过滤您的列表。
  • 那里尝试。好吧,它肯定会失败,但 OP 想要列表理解并且考虑到限制,这并非易事。

标签: python python-3.x


【解决方案1】:

我建议直接生成您想要的数字,而不是事后过滤列表。函数itertools.product 可用于生成所有的满足,(0, 0)(0, 2),...,等等。然后,只需将200 添加到每个。

from itertools import product

vals = [200 + int(''.join(t)) for t in product('02468', repeat=2)]

这有点可扩展。假设您想生成所有从 2000 开始并以 4888 结尾的四位数的偶数,那么您可以使用:

vals = [int(''.join(t)) for t in product(*(('24',) + ('02468',) * 3))]

如果你想要不那么干净的边界,你可以在之后过滤结果。

【讨论】:

  • 每个人都得到了很多反对票,可能是由 SO python 反对票警察,因为“没有尝试”。我认为这很可笑,所以我在这里给每个人投票,因为有时你会因为回答血腥显而易见的问题而获得 6 次投票……如果有些反对者愿意发布一个精彩的答案,我们会很高兴地投票。
  • 优秀的方法,它比这里的其他答案快 30 倍到 200 倍。干得好!
【解决方案2】:

带有字符串和集合

您可以定义一组可接受的数字并过滤仅使用这些数字的整数:

>>> allowed_digits = set('02468')
>>> [i for i in range(200,300) if set(str(i)) <= allowed_digits]
[200, 202, 204, 206, 208, 220, 222, 224, 226, 228, 240, 242, 244, 246, 248, 260, 262, 264, 266, 268, 280, 282, 284, 286, 288]

所需的属性并不是真正为数字定义的,而是为它的十进制表示。我想说在这种情况下使用str() 是有意义的。

算术

还可以使用算术检查每个数字是否为偶数,例如使用递归函数:

def all_even(i):
    if i == 0:
        return True
    return (i % 10) % 2 == 0 and all_even(i // 10)

print(all_even(123456))
# False
print(all_even(24680))
# True

可以这样使用:

>>> [i for i in range(200,300) if all_even(i)]
[200, 202, 204, 206, 208, 220, 222, 224, 226, 228, 240, 242, 244, 246, 248, 260, 262, 264, 266, 268, 280, 282, 284, 286, 288]

性能

Jared Goguen 的出色 answer 是迄今为止最快的:

In [46]: %timeit [int(''.join(t)) for t in product('02468', repeat=5)]
2.19 ms ± 12.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

这很有意义,因为它直接生成列表,无需过滤任何内容。

然后是all_even 方法:

In [17]: %timeit [i for i in range(100000) if all_even(i)]
69.5 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

后跟字符串和set方法:

In [15]: %timeit [i for i in range(100000) if set(str(i)) <= allowed_digits]
104 ms ± 167 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

随后是@jmd_dk 的answer

In [14]: %timeit [res for res in range(100000) if all(int(digit)%2 == 0 for digit in str(res))]
245 ms ± 1.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

随后是 Jamie Counsell 的answer

In [16]: %timeit [res for res in range(1,100000) if all((int(res/math.pow(10, power) % 2) == 0) for power in range(0, int(math.log10(res)) + 1))]
447 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    【解决方案3】:

    这将保留原始列表并单独打印每个数字:

    jail = [res for res in range(200,300)if res % 2 ==0 ]
    for number in jail:
        if all(int(digit)%2 == 0 for digit in str(number)):
            print(number)
    

    如果您只想要jail 列表中的这些特殊数字,只需将条件放入列表的创建中:

    jail = [res for res in range(200,300) if all(int(digit)%2 == 0 for digit in str(res))]
    

    这些解决方案依赖于这样一个事实,即每个数字都可以通过迭代整数的str 表示来获得。

    【讨论】:

    • 我不会赞成那个,但它不值得-1。当人们在没有充分理由或评论的情况下投反对票时,就会发生这种情况:他们会得到相反的效果。
    • 为什么不呢?对我来说,这似乎是最 Pythonic 和最直接的解决方案。
    • jail = [res for res in range(200,300) if all(int(digit)%2 == 0 for digit in str(res))] 我同意这是一个更好的答案:紧凑且仍然可读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    相关资源
    最近更新 更多