簡體   English   中英

在沒有 Itertools 的情況下從兩個列表生成唯一的對

[英]Generate Unique Pairs From Two Lists Without Itertools

我在一個列表上循環了兩次,想要捕獲所有唯一的對,而不是所有的組合——即。 對中的順序無關緊要

listy=[0,1,2]
out=[]
for i in listy:
   for j in listy:
      out.append([i,j])

我得到的輸出是 [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0], [2,1],[2,2]]

我正在尋找的是 [[0,0],[0,1],[0,2],[1,1],[1,2],[2,2]]

一種可能的解決方案是,

listy=[0,1,2]
out=[]
for i in listy:
   for j in listy:
      pair=set([i,j])
      if pair not in out:
          out.append(pair)

這會產生 [{0},{0,1},{0,2},{1},{1,2},{2}]

但是,這會在繁重的腳本中造成效率低下(列表很長),而且我也不想要集合列表。 我想要一個列表列表。

有沒有更好的方法可以在不使用 itertools 的情況下實現這一點(我想要一個實現,我也可以應用到 javascript 而無需太多重新思考)

選項 1 - “小修復”

一個微不足道的“修復”將是:

listy=[0,1,2]
out=set()
for i in listy:
    for j in listy:
        if (i, j) not in out and (j, i) not in out:
            out.add((i,j))

結果是:

{(0, 1), (1, 2), (0, 0), (1, 1), (0, 2), (2, 2)}

然而,這不是一個有效的實現,因為我們必須檢查兩次元素是否在列表中。

選項 2 - 更有效的實施

您可以使用數組的簡單掃描來實現您的目標:

listy=[0,1,2]
out = [(i, j) for i in range(len(listy)) for j in range(i, len(listy))]

注意:我對對使用元組,您可以使用以下方法輕松地將其更改為列表列表:

out = [[i, j] for i in range(len(listy)) for j in range(i, len(listy))]

我根本不懂javascript,但如果有類似於列表理解的東西,我會試試這個:

listy = [0,1,2]
pairs = [[i, j] for i in listy for j in listy if i <= j]

對的內容完全符合您的要求:

[[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]

直接從輸入list生成所需結果的itertools.combinations_with_replacement(listy, 2) (匹配您想要的行為)的最直接翻譯是:

listy = [0,1,2]
out = []
for idx, i in enumerate(listy):
   for j in listy[idx:]:
      out.append([i, j])

唯一的變化是使用enumerate (在迭代時獲取當前索引)並切片內部循環中使用的listy (因此它從與外部循環的當前運行相同的索引開始)。

這以最小的開銷獲得了所請求的確切結果(它確實為每個內部循環制作了list的淺表副本,大小減小了一次,但這在 Python 中相當快;除非list很大,否則它應該是一個非常小的成本)。 如果您需要避免切片,您可以使內部循環成為帶有索引的基於索引的循環(但在實踐中,索引的開銷足夠高,以至於它經常會輸給切片):

listy = [0,1,2]
out = []
for idx, i in enumerate(listy):
   for idxj in range(idx, len(listy)):
      out.append([i, j[idxj]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM