次のような関数があるとします。
def getNeighbors(vertex)
これは、指定された頂点に隣接する頂点のリストを返します。今、私は隣人のすべての隣人のリストを作成したいと思います。私はそれを次のようにします:
listOfNeighborsNeighbors = []
for neighborVertex in getNeighbors(vertex):
listOfNeighborsNeighbors.append(getNeighbors(neighborsVertex))
それを行うためのよりPython的な方法はありますか?
[x for n in getNeighbors(vertex) for x in getNeighbors(n)]
または
sum(getNeighbors(n) for n in getNeighbors(vertex), [])
いつものように、itertoolsモジュールにはソリューションが含まれています:
>>> l1=[1, 2, 3]
>>> l2=[4, 5, 6]
>>> l3=[7, 8, 9]
>>> import itertools
>>> list(itertools.chain(l1, l2, l3))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
リストの追加は+とsum()で行うことができます:
>>> c = [[1, 2], [3, 4]]
>>> sum(c, [])
[1, 2, 3, 4]
速度が重要な場合は、これを使用することをお勧めします。
_from operator import iadd
reduce(iadd, (getNeighbors(n) for n in getNeighbors(vertex)))
_
このコードのポイントは、リスト全体を_list.extend
_で連結することです。リスト内包表記では、_list.append
_を呼び出す場合と同様に、1つのアイテムを1つずつ追加します。これにより、オーバーヘッドが少し節約され、前者(私の測定によると)は約3倍速くなります。 (iadd
演算子は通常_+=
_として記述され、_list.extend
_と同じことを行います。)
リスト内包表記(Ignacioによる最初のソリューション)を使用することは、通常は依然として正しい方法であり、読みやすくなっています。
ただし、sum(..., [])
は2次時間で実行されるため、絶対に使用しないでください。 多数リスト(100以上)の場合、これは非常に非現実的です。
速度で並べ替え:
list_of_lists = [[x,1] for x in xrange(1000)]
%timeit list(itertools.chain(*list_of_lists))
100000 loops, best of 3: 14.6 µs per loop
%timeit list(itertools.chain.from_iterable(list_of_lists))
10000 loops, best of 3: 60.2 µs per loop
min(timeit.repeat("ll=[];\nfor l in list_of_lists:\n ll.extend(l)", "list_of_lists=[[x,1] for x in xrange(1000)]",repeat=3, number=100))/100.0
9.620904922485351e-05
%timeit [y for z in list_of_lists for y in z]
10000 loops, best of 3: 108 µs per loop
%timeit sum(list_of_lists, [])
100 loops, best of 3: 3.7 ms per loop
_itertools.chain
_アプローチは線形時間で実行されるため(sum(...)は4次時間で実行されます)、@ Jochenは動的な長さのリストを処理する方法を示していません。 OPの質問に対する解決策を次に示します。
_import itertools
list(itertools.chain(*[getNeighbors(n) for n in getNeighbors(vertex)]))
_
Iterableで十分であれば、list(...)
呼び出しを取り除くことができます。
。extend()(定位置で更新)をsum()(毎回新しいオブジェクト)の代わりにreduceと組み合わせて使用する方が効率的ですが、テストするのが面倒ですそれ :)
mylist = [[1,2], [3,4], [5,6]]
reduce(lambda acc_l, sl: acc_l.extend(sl) or acc_l, mylist)