如何使用Python的itertools模块从整数元组中删除最后一个元素为“0”的元组?

4
我有以下代码来创建一个包含多个整数对的元组:
iterable = (
    tuple(zip([0, 1, 2], _))
    for _ in product(range(9), repeat=3)
)
next(iterable)  # First element is not needed
print(list(iterable))

# This code produces: [((0, 0), (1, 0), (2, 1)), ... , ((0, 8), (1, 8), (2, 8))]

但是如果元组的最后一个元素是"0"(例如(0, 0)或(2, 0)),我需要删除该元组。因此,新的列表应该像这样:
[((2, 1),), ... , ((1, 2), (2, 7)), ((1, 2), (2, 8)), ... , ((0, 8), (1, 8), (2, 8))]

我实际上通过以下代码实现了这个目标,但我觉得这不是正确的方法,我不知道。
x = ()
for i in iterable:
    y = ()
    for j in i:
        if j[-1] != 0:
            y += (j,)
    x += (y,)
print(list(x))

如何使用itertools模块并在一行内完成这个任务?如果需要的话,我可以修改问题顶部的代码,以便在一行内创建所需的列表。
谢谢。

你的代码背后的逻辑是什么?你能解释一下那些元组代表/看起来像什么吗? - Gugu72
你的代码背后有什么逻辑?你能解释一下那些元组代表什么/看起来像什么吗? - Gugu72
你的代码背后的逻辑是什么?你能解释一下那些元组代表什么或者是什么样子的吗? - undefined
2个回答

6
使用filter()函数从zip()的结果中删除以0结尾的元素。
iterable = (
    tuple(filter(lambda x: x[-1] != 0, zip([0, 1, 2], _)))
    for _ in product(range(9), repeat=3)
)

2
这段代码出现了错误 NameError: name 't' is not defined - serhatcelik
3
这段代码出现了错误NameError: name 't' is not defined - serhatcelik
除非t是一个元组的元组,否则您无法检查t是否等于零。 - Gugu72
除非t是一个元组的元组,否则你无法检查t是否等于零。 - Gugu72
@serhatcelik,我误解了你想要检查0的位置,我已经更新了答案。 - Barmar
显示剩余5条评论

1

更像是itertools且更短+更快,使用compress

iterable = (
    tuple(compress(zip((0, 1, 2), p), p))
    for p in product(range(9), repeat=3)
)

此外:

  • 当你使用值时,请不要使用名称_,它是我们不使用的值的常规名称。

  • 使用元组(0, 1, 2),这样Python可以始终将其作为常量简单加载,而无需每次构建一个新的列表[0, 1, 2]。或者使用enumerate

    iterable = (
        tuple(compress(enumerate(p), p))
        for p in product(range(9), repeat=3)
    )
    
一个基准:
 386.0 ± 2.2 μs  Kelly_enumerate
 509.8 ± 3.2 μs  Kelly_zip
 751.6 ± 6.2 μs  Barmar

代码:

from timeit import timeit
from statistics import mean, stdev
from collections import deque
from itertools import *

def Kelly_zip():
    iterable = (
        tuple(compress(zip((0, 1, 2), p), p))
        for p in product(range(9), repeat=3)
    )
    return iterable

def Kelly_enumerate():
    iterable = (
        tuple(compress(enumerate(p), p))
        for p in product(range(9), repeat=3)
    )
    return iterable

def Barmar():
    iterable = (
        tuple(filter(lambda x: x[-1] != 0, zip([0, 1, 2], _)))
        for _ in product(range(9), repeat=3)
    )
    return iterable

funcs = Kelly_zip, Kelly_enumerate, Barmar

expect = list(Barmar())
for f in funcs:
    assert list(f()) == expect

times = {f: [] for f in funcs}
def stats(f):
    ts = [t * 1e6 for t in sorted(times[f])[:10]]
    return f'{mean(ts):6.1f} ± {stdev(ts):3.1f} μs '

consume = deque(maxlen=0).extend
for _ in range(100):
    for f in funcs:
        t = timeit(lambda: consume(f()), number=10) / 10
        times[f].append(t)

for f in sorted(funcs, key=stats):
    print(stats(f), f.__name__)

尝试在线操作!


我不知道这些信息。谢谢分享! - serhatcelik
我不知道这些信息。谢谢分享! - serhatcelik
@serhatcelik 还请注意我现在添加的基准测试。 - Kelly Bundy
@serhatcelik 还请注意我现在添加的基准。 - Kelly Bundy
@serhatcelik 还请注意我现在添加的基准。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接