簡體   English   中英

使用組合復制列表中的項目

[英]Duplicating items in a list with combinations

Python 中有兩個列表:

i = [0, 1, 2, 3, 4]
j = [1, 4]

我正在嘗試復制 j 中的值並獲取所有唯一組合。 i可以是任何(可散列的)值的列表。 它永遠不會包含重復項,但值的順序很重要。 j始終是i的子集。 整數僅用作示例,實際值可以是字符串。

output 應該是:

[
[0, 1, 2, 3, 4], # i is always included as a combination - this can be added independently if required
[0, 1, 1, 2, 3, 4],
[0, 1, 1, 2, 3, 4, 4],
[0, 1, 2, 3, 4, 4]
]

為清楚起見,另一個示例:

i = ["B", "E", "C", "A", "D"]
j = ["C", "A", "D"]

# desired output - the order of i should be preserved
# but the order of lists within the outer list is unimportant
[
["B", "E", "C", "A", "D"], # original list
["B", "E", "C", "C", "A", "D"], # duplicated C
["B", "E", "C", "C", "A", "A", "D"], # duplicated C, A
["B", "E", "C", "C", "A", "D", "D"], # duplicated C, D
["B", "E", "C", "C", "A", "A", "D", "D"], # duplicated C, A, D
["B", "E", "C", "A", "A", "D"], # duplicated A
["B", "E", "E", "C", "A", "A", "D", "D"], # duplicated A, D
["B", "E", "C", "A", "D", "D"], # duplicated D
]

我嘗試了各種列表理解方法,以及一些 itertools 函數,如產品和組合,但還沒有找到令人滿意的解決方案。

半工半程的嘗試如下,雖然這是一種丑陋的方法:

i = [0, 1, 2, 3, 4]
j = [1, 4]

all_lists = [i]
for x in j:
    new_list = i.copy()
    new_list.insert(i.index(x), x)
    all_lists.append(new_list)

print(all_lists)
# [[0, 1, 2, 3, 4], [0, 1, 1, 2, 3, 4], [0, 1, 2, 3, 4, 4]]
# still missing the [0, 1, 1, 2, 3, 4, 4] case

問題的背景 - i是 networkx 網絡中的節點列表, j是具有自環的節點列表。 結果是節點之間所有非簡單路徑的組合。

您嘗試使用itertools是對的。 function combinations就是您想要的。 只需遍歷所有可能的長度(從 0 到 len(j)):

import itertools

i = ["B", "E", "C", "A", "D"]
j = ["C", "A", "D"]

result = []
for l in range(len(j) + 1):
    for j_subset in itertools.combinations(j, l):
        result.append(sorted(i + list(j_subset), key=lambda x: i.index(x)))


print(result)

您說列表可以包含任何類型的元素。 這是使用自定義 class Node執行相同操作的示例:

import itertools

# here is my custom Node class
class Node():
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):
        return self.name == other.name

# the names of the nodes
names_i = ["B", "E", "C", "A", "D"]
names_j = ["C", "A", "D"]


# the actual data we are working with - lists of distinct nodes
i = [Node(name) for name in names_i]
j = [Node(name) for name in names_j]

result = []

for l in range(len(j) + 1):
    for j_subset in itertools.combinations(j, l):
        result.append(sorted(i + list(j_subset), key=lambda x: i.index([node for node in i if node == x][0])))


# print the raw result
print(result)

# print the result but just showing the node names
print([[node.name for node in result_element] for result_element in result])

使用類的主要區別在於,使用相同名稱實例化的兩個節點類不是同一個 object,因此sorted鍵中的i.index(x)將不起作用,因為i中沒有j的元素(即使它們有同名,並且“相等”)。 如果您願意,我可以對此進行更多解釋。

更改以反映j是要復制的值的列表

for k in range(len(j) + 1):
    for n in itertools.combinations(j, k):
        lst = i[:]
        for el in n:
            ix = lst.index(el)
            lst.insert(ix, lst[ix])
        print(lst)

使用insert進行編輯比我以前的效率更高

這是你要找的嗎?

In [1]: %paste                                                                                                                                                                                                                                                                       
from itertools import combinations

i = [0, 1, 2, 3, 4]
j = [1, 4]

res = []
for r in range(len(j) + 1):
    for comb in combinations(j, r):
        res.append(sorted(i + list(comb)))
print(res)

## -- End pasted text --
[[0, 1, 2, 3, 4], [0, 1, 1, 2, 3, 4], [0, 1, 2, 3, 4, 4], [0, 1, 1, 2, 3, 4, 4]]

In [2]: 

暫無
暫無

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

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