234

実装しようとしているアルゴリズムに頭を悩ませています。2 つのリストがあり、2 つのリストから特定の組み合わせを取得したいと考えています。

これが例です。

names = ['a', 'b']
numbers = [1, 2]

この場合の出力は次のようになります。

[('a', 1), ('b', 2)]
[('b', 1), ('a', 2)]

数字よりも名前の方が多いかもしれませんlen(names) >= len(numbers)。3 つの名前と 2 つの数字の例を次に示します。

names = ['a', 'b', 'c']
numbers = [1, 2]

出力:

[('a', 1), ('b', 2)]
[('b', 1), ('a', 2)]
[('a', 1), ('c', 2)]
[('c', 1), ('a', 2)]
[('b', 1), ('c', 2)]
[('c', 1), ('b', 2)]
4

11 に答える 11

209

上記の最も単純なものよりも単純かもしれません:

>>> a = ["foo", "bar"]
>>> b = [1, 2, 3]
>>> [(x,y) for x in a for y in b]  # for a list
[('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)]
>>> ((x,y) for x in a for y in b)  # for a generator if you worry about memory or time complexity.
<generator object <genexpr> at 0x1048de850>

インポートなしで

于 2016-08-21T13:33:40.177 に答える
130

:この回答は、上記の特定の質問に対するものです。あなたがGoogleからここにいて、Pythonでデカルト積を取得する方法を探しているだけの場合、itertools.productまたは単純なリスト内包表記が探しているものかもしれません-他の回答を参照してください。


と仮定しlen(list1) >= len(list2)ます。次に、あなたが望むように見えるのは、len(list2)からの長さのすべての順列を取得しlist1、それらを list2 の項目と一致させることです。パイソンでは:

import itertools
list1=['a','b','c']
list2=[1,2]

[list(zip(x,list2)) for x in itertools.permutations(list1,len(list2))]

戻り値

[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]
于 2012-10-17T13:35:11.927 に答える
30

この関数として提供されている、一意の組み合わせのみで乗算されたリストを探していました。

import itertools
itertools.combinations(list, n_times)

Python ドキュメント itertoolsからの抜粋として、探しているものを見つけるのに役立つかもしれません。

Combinatoric generators:

Iterator                                 | Results
-----------------------------------------+----------------------------------------
product(p, q, ... [repeat=1])            | cartesian product, equivalent to a 
                                         |   nested for-loop
-----------------------------------------+----------------------------------------
permutations(p[, r])                     | r-length tuples, all possible 
                                         |   orderings, no repeated elements
-----------------------------------------+----------------------------------------
combinations(p, r)                       | r-length tuples, in sorted order, no 
                                         |   repeated elements
-----------------------------------------+----------------------------------------
combinations_with_replacement(p, r)      | r-length tuples, in sorted order, 
                                         | with repeated elements
-----------------------------------------+----------------------------------------
product('ABCD', repeat=2)                | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)                  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)                  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD
于 2016-11-29T21:52:35.463 に答える
12

1行のリスト内包表記を試してみてください:

>>> [name+number for name in 'ab' for number in '12']
['a1', 'a2', 'b1', 'b2']
>>> [name+number for name in 'abc' for number in '12']
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']
于 2017-01-10T19:26:39.843 に答える
9

結果をフラット化リストにするための、interjay からの回答の小さな改善。

>>> list3 = [zip(x,list2) for x in itertools.permutations(list1,len(list2))]
>>> import itertools
>>> chain = itertools.chain(*list3)
>>> list4 = list(chain)
[('a', 1), ('b', 2), ('a', 1), ('c', 2), ('b', 1), ('a', 2), ('b', 1), ('c', 2), ('c', 1), ('a', 2), ('c', 1), ('b', 2)]

このリンクからの参照

于 2013-12-19T15:02:10.337 に答える
7

itertoolsフラット化されたリストとしてなし:

[(list1[i], list2[j]) for i in range(len(list1)) for j in range(len(list2))]

またはPython 2で:

[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]
于 2016-03-11T11:32:14.610 に答える