我想从这两个列表中创建一个所有组合的列表,其中每个组合也是一个列表。
例如
给出两个列表:[1,2,3]
和[True, False]
组合:
[(1, False), (2, False), (3, False)]
[(1, False), (2, False), (3, True )]
[(1, False), (2, True ), (3, False)]
[(1, True ), (2, False), (3, False)]
[(1, False), (2, True ), (3, True )]
[(1, True ), (2, False), (3, True )]
[(1, True ), (2, True ), (3, False)]
[(1, True ), (2, True ), (3, True )]
应该有2^n
个组合,其中n
是数字的数量。
编辑:
尝试执行以下操作:
[(n, b) | n <- [1,2,3], b <- [True, False]]
(,) <$> [1,2,3] <*> [True, False]
答案 0 :(得分:3)
我们可以避免使用length
,这可能是不安全的,因为列表的长度可以无限。通过使用递归或文件夹模式,我们可以避免这种情况:
{-# LANGUAGE TupleSections #-}
allComb :: [b] -> [a] -> [[(a,b)]]
allComb vs = go
where go [] = [[]]
go (x:xs) = (:) <$> map (x,) vs <*> go xs
或在单层中使用折叠图案:
allComb :: [b] -> [a] -> [[(a,b)]]
allComb vs = foldr (\x -> ((:) <$> map (x,) vs <*>)) [[]]
例如:
Prelude> allComb [False, True] [1,2,3]
[[(1,False),(2,False),(3,False)],[(1,False),(2,False),(3,True)],[(1,False),(2,True),(3,False)],[(1,False),(2,True),(3,True)],[(1,True),(2,False),(3,False)],[(1,True),(2,False),(3,True)],[(1,True),(2,True),(3,False)],[(1,True),(2,True),(3,True)]]
以上方法不适用于无限列表,尽管我们可以在给定第一个列表至少包含一个元素的情况下,稍稍更改代码以生成结果的第一个元素:将列表中所有元素压缩的列表该项目的第二个清单。我将其保留为练习。
答案 1 :(得分:2)
可以通过定义来产生所需的输出
foo :: [a] -> [b] -> [[(a, b)]]
foo nums bools =
map (zip nums) . sequence $ replicate (length nums) bools
=
let n = length nums
in
[ zip nums bs | bs <- sequence $ replicate n bools]
并致电
foo [1,2,3] [False, True]
该呼叫等同于
let nums = [1,2,3]
bools = [False, True]
n = 3
in
[ zip nums bs | bs <- sequence $ replicate n bools]
=
[ zip [1,2,3] bs | bs <- sequence $ replicate 3 [False, True]]
=
[ zip [1,2,3] (b:bs) | b <- [False, True]
, bs <- sequence $ replicate 2 [False, True]]
=
[ zip [1,2,3] (b:c:bs) | b <- [False, True]
, c <- [False, True]
, bs <- sequence $ replicate 1 [False, True]]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence $ replicate 0 [False, True] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence [] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- [[]] ]
=
[ zip [1,2,3] (b:c:d:[]) | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
即
[ zip [1,2,3] [b,c,d] | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
如果对最后一个表达式求值,我们也会得到相同的结果。
用两个可用值的每种可能组合填充三个空格,就像具有从3个空格到2个值的所有可能函数一样,无论这些空格和值是什么。
数学家将此函数写为 2 3 ,实际上,我们得到了2^3 = 8
输出。
编辑: sequence ... replicate
组合实际上只是在重新实现另一个内置replicateM
:
foo ns bs = map (zip ns) (replicateM (length ns) bs)
因为replicateM n a
与sequence (replicate n a)
相似,但实际上并未建立中间列表。
对于pointfree迷来说,我们可以拥有
foo ns = map (zip ns) . replicateM (length ns)
= (.) ((map . zip) ns) ((replicateM . length) ns)
= ((.) . map . zip <*> replicateM . length) ns
即
foo = (.) . map . zip <*> replicateM . length
答案 2 :(得分:2)
这不是最直接或最有效的答案。
但是使用How to generate a list of all possible strings from shortest to longest中的技术,我们可以生成所有可能的布尔序列的列表。我们采用与第二个列表相同的长度,然后用该列表压缩它们。
allBoolPermutations :: Int -> [[Bool]]
allBoolPermutations n = takeWhile (\l -> length l == n)
$ dropWhile (\l -> length l < n)
$ allBools
where
allBools = [ c : s | s <- []:allBools, c <- [True, False]]
zipWithBoolPermutations :: [a] -> [[(a, Bool)]]
zipWithBoolPermutations someList = map (zip someList)
(allBoolPermutations (length someList))
然后zipWithBoolPermutations [1,2,3]
应该给您您想要的东西。
答案 3 :(得分:2)
简短简短:
setup(name="<module name>",
version="0.1",
packages=['<package name if any or ignore>'],
install_requires=['pandas==0.25.1']
)
或更没有意义,但也许更容易理解:
traverse ((<$> [True, False]) . (,)) [1,2,3]
内部函数({-# LANGUAGE TupleSections #-}
traverse (\x -> (x,) <$> [True, False]) [1,2,3]
或(<$> [True, False]) . (,)
)采用诸如\x -> (x,) <$> [True, False]
之类的每个元素,并将其转换为1
。如果您将[(1,True),(1,False)]
视为traverse f
,则sequence . fmap f
部分意味着对列表中的每一件事都起作用(产生fmap f
),而{{1} }部分意味着将它们与List应用程序(用于模拟非确定性模型)组合以创建所有可能的组合(产生[[(1,True),(1,False)],[(2,True),(2,False)],[(3,True),(3,False)]]
)。