python - 使用组合复制列表中的项目
问题描述
在 Python 中有两个列表:
i = [0, 1, 2, 3, 4]
j = [1, 4]
我正在尝试复制 j 中的值并获取所有唯一组合。
i
可以是任何(可散列的)值的列表。它永远不会包含重复项,但值的顺序很重要。j
始终是 的子集i
。整数仅用作示例,实际值可以是字符串。
输出应该是:
[
[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
. 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)
您说列表可以包含任何类型的元素。这是一个使用自定义类做同样事情的例子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])
使用类的主要区别在于,使用相同名称实例化的两个 Node 类不是同一个对象,因此i.index(x)
在您的sorted
键中将不起作用,因为没有元素j
在i
(即使它们具有相同的名称,并且是“相等的” )。如果您愿意,我可以对此进行更多解释。
推荐阅读
- macos - 无法在 macbook pro 上卸载内置键盘(kext 卸载)
- javascript - 以块或 ReadableStream 的形式发送 XMLHttpRequest 数据以减少大数据的内存使用
- c++ - 具有两个限制的最大对数的算法
- javascript - JS:点击 TD 元素时如何获取它的 innerHTML?
- aws-lambda - 在 AWS Lambda 403 错误:无法满足请求
- python - 如果条件为fale,则中断尝试并直接进入异常
- docker - Docker“干净启动”
- node.js - 允许 MongoDB 集合中不同名称的相同日期?
- python - 如何在命令中提及成员可选?
- ms-word - MS Word 邮件合并:MERGESEQ 和 MOD