【问题标题】:All the combinations without using itertools?不使用 itertools 的所有组合?
【发布时间】:2018-05-05 14:01:45
【问题描述】:

我想知道如何使用 Python 中的 itertools 编写一个算法,为我提供数字列表重复和没有的所有可能组合。

例如:列表[1,2]的所有可能组合:

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

列表[1,2,3] 的所有可能组合。然后,该算法将在一个列表中为我提供 27 (33) 个不同的列表。

这是我的代码:

def all_possibilities(list):
    result = [list]

    for i in list:
        new_list1 = list[:]

        for k in range(len(list)):
            new_list2 = list[:]
            new_list1[k] = i
            new_list2[k] = i
            if new_list1 != list:
                result.append(new_list1)
            if new_list2 != list:
                result.append(new_list2)

    for u in result:
        for y in result:
            if u == y and (u is y) == False:
                result.remove(y)

    return (len(result),result)

【问题讨论】:

  • 您在实施中遇到了什么具体问题?
  • 如果您正在寻找与itertools.permutations 等效的纯python,您可以检查此方法的实现是docs
  • 你需要学习的概念是递归。
  • 我知道递归的概念,但我尝试多次编写它,但我从来没有得到所有可能的解决方案。
  • 向我们展示您的尝试,并向我们展示它是如何失败的。

标签: python list


【解决方案1】:

您可以编写自己的product 方法来找出多个列表的cartesian product

def cartesian_product(*lists):
  result = [[]]
  for list in lists:
    result = [x + [y] for x in result for y in list]
  return result  
l = [1, 2, 3]
lst = [l for i in l]
x = cartesian_product(*lst)
for tuple in x:
   print(tuple)

输出

(1, 1)
(1, 2)
(2, 1)
(2, 2)   

【讨论】:

  • “不使用 itertools”在问题中
  • @MihaiAlexandru-Ionut 你能解释一下第 4 行发生了什么吗?提前致谢
  • @PaulvanTieghem,基本上它创建了一个列表 [[1],[2],[3]] 然后[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]] 等等。
【解决方案2】:

这实际上是用替换进行组合。您可以调整组合的大小。我让它返回一个元组,因为元组是不可变的,并且元组操作比列表操作快。但是,如果需要,您可以轻松地使其返回列表列表。干杯

def seq_slicer(container, step=10):
    """(container)->container
    Returns slices of container in chunks of step.
    Great selecting chunks of a sequence in predetrmined slices efficiently.

    In the event where step is greater than the length of the sequence to be sliced,
    the slice taken will be the length of the sequence.

    >>> [i for i in seq_slicer(range(40), 10)]
    [range(0, 10), range(10, 20), range(20, 30), range(30, 40)]

    >>> [i for i in seq_slicer(range(41), 10)]
    [range(0, 10), range(10, 20), range(20, 30), range(30, 40), range(40, 41)]

    >>> [c for c in seq_slicer("abcdefghijklm", 3)]
    ['abc', 'def', 'ghi', 'jkl', 'm']

    >>> [c for c in seq_slicer(list("abcdefghijklm"), 3)]
    [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['j', 'k', 'l'], ['m']]

    Author: Xero
    License: Apache V2
    """
    i = 0
    span = len(container)
    while i < span:
        yield container[i:i+step]
        i += step

def combinations_with_replacement(seq, num):
    """(sequence type, integer)->list
    return every possible combination of num elements from seq in lexicographic order
    >>> combinations_with_replacement([1, 2], 2)
    ((1, 1), (1, 2), (2, 1), (2, 2))


    Author: Xero
    License: Apache V2
    """
    lst = []
    _seq = tuple(seq)
    slices = [c for c in seq_slicer(_seq, num-1)]
    for elem in seq:
        for combo in [(elem,) + body for body in slices]:
            lst.append(combo)
    return tuple(lst)

【讨论】:

  • 非常感谢您的帮助!
  • @PaulvanTieghem,欢迎您。请将答案标记为已接受,如果它对您有用并且您觉得它有用,请点赞
  • @XeroSmith,为你的答案投票。我知道写一个长而正确的答案时的感觉,没有人赞成它,以表彰为回答问题所投入的努力和时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多