Skip to main content
 首页 » 编程设计

python:如何在不重复项目的情况下制作可迭代产品

2025年05月04日19虾米姐

我需要一个功能与 itertools.product 类似但没有重复项的函数。

例如:

no_repeat_product((1,2,3), (5,6)) 
= ((1,5), (None,6), (2,5), (None,6), ...(None,6)) 
no_repeat_product((1,2,3), (5,6), (7,8)) 
= ((1,5,7), (None,None,8), (None,6,7), (None,None,8), ...(None,None,8)) 

有什么想法吗?

编辑: 我的措辞不正确。我的意思是不重复连续输出值中相同的数字。
例如,

itertools.product((1,2,3), (4,5), (6,7) is 
(1,4,6) 
(1,4,7), etc   

此处 1,4 在输出中出现了两次。所以,当数字与之前的项目相同时,我想跳过写数字。所以,我想要的输出是:

(1,4,6)   
(None,None,7)   

当为None时,理解为与它在结果中的前一项相同。

进一步编辑:

我的解释仍然不够清晰。 假设我有书籍 list 、章节编号和页码。假设每本书的章节数相同,并且每章的页数相同。 所以,列表是 (book1, book2, book3), (chap1, chap2), (page1, page2, page3)。
现在,假设我想收集每个页面的描述:
itertools.product 会给我:

(book1, chap1, page1), (book1, chap1, page2)..... (book3, chap2, page3) 

如果我依次排列了这些页面,我就不需要重复描述了。所以,如果书和章节相同,在第二页,我不需要书名和章节名 所以,输出应该是:

(book1, chap1, page1), (None, None, page2), ..    
(when the pages of first chapter are over..) (None, chap2, page1), (None, None, page2)......   
(when the chapters of the first book are over..)(book2, chap1, page1)..............   
(None, None, page3)   

请您参考如下方法:

根据您的评论“因为 (None,None,8) 没有连续出现”,我假设您只想 None-ify 元素出现在之前的输出中。

def no_repeat_product(*seq): 
    previous = (None,)*len(seq) 
    for vals in itertools.product(*seq): 
        out = list(vals) 
        for i,x in enumerate(out): 
            if previous[i] == x: 
                out[i] = None 
        previous = vals 
        yield(tuple(out))    

或者,如果您更喜欢更紧凑和高效(但可读性较差)的版本:

def no_repeat_product(*seq): 
    previous = (None,)*len(seq) 
    for vals in itertools.product(*seq): 
        out = tuple((y,None)[x==y] for x,y in itertools.izip(previous, vals)) 
        previous = vals 
        yield(out)        

他们都做同样的事情,并产生以下结果:

for x in no_repeat_product((1,2,3), (5,6), (7,8)):  
    print x  

输出:

(1, 5, 7) 
(None, None, 8) 
(None, 6, 7) 
(None, None, 8) 
(2, 5, 7) 
(None, None, 8) 
(None, 6, 7) 
(None, None, 8) 
(3, 5, 7) 
(None, None, 8) 
(None, 6, 7) 
(None, None, 8) 

以您更新后的问题为例:

books = ("Book 1", "Book 2") 
chapters = ("Chapter 1", "Chapter 2") 
pages = ("Page 1", "Page 2", "Page 3") 
 
s1 = max(map(len, books)) + 2  # size of col 1 
s2 = max(map(len, chapters)) + 2  # size of col 2 
x = lambda s, L: (s, "")[s == None].ljust(L)  # Left justify, handle None 
 
for book, chapter, page in no_repeat_product(books, chapters, pages): 
    print x(book, s1), x(chapter, s2), page 

这给你:

Book 1   Chapter 1   Page 1 
                     Page 2 
                     Page 3 
         Chapter 2   Page 1 
                     Page 2 
                     Page 3 
Book 2   Chapter 1   Page 1 
                     Page 2 
                     Page 3 
         Chapter 2   Page 1 
                     Page 2 
                     Page 3