20

与えられた:リストなどのリスト[[3,2,1], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]

Todo:すべてのサブリストの中で最も長い共通プレフィックスを見つけます。

存在する:別のスレッド「Pythonでセットを使用しない2つのリスト間の共通要素」では、Python2.7より上で使用可能な「Counter」を使用することをお勧めします。ただし、現在のプロジェクトはpython 2.6で記述されているため、「Counter」は使用されません。

私は現在、次のようにコーディングしています。

l = [[3,2,1], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]
newl = l[0]
if len(l)>1:
    for li in l[1:]:
    newl = [x for x in newl if x in li]

しかし、私はそれがあまりPythonicではないと思います、コーディングのより良い方法はありますか?

ありがとう!

新しい編集:申し訳ありませんが、私の場合、「l」のリストの共有要素は同じ順序であり、常に0番目の項目から始まります。だからあなたは次のようなケースはありません[[1,2,5,6],[2,1,7]]

4

6 に答える 6

57

os.path.commonprefix()リストに適しています:)

>>> x = [[3,2,1], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]
>>> import os
>>> os.path.commonprefix(x)
[3, 2, 1]
于 2014-01-28T23:31:38.230 に答える
18

私はそれがどれほどpythonicであるかわかりません

from itertools import takewhile,izip

x = [[3,2,1], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]

def allsame(x):
    return len(set(x)) == 1

r = [i[0] for i in takewhile(allsame ,izip(*x))]
于 2012-06-29T14:41:24.823 に答える
2

サンプルコードを考えるとreduce(set.intersection, map(set, l))、最初のリストの最初の順序を保持するバージョンが必要なようです。

これには、文体の改善ではなく、アルゴリズムの改善が必要です。「pythonic」コードだけでは、ここでは何の役にも立ちません。すべてのリストで発生するすべての値に当てはまる必要がある状況について考えてみてください。

リストのリストが与えられた場合、値はリストで発生する場合にのみすべてのリストで発生しnlistます。ここnlistで、はリストの総数です。

各値がすべてのリストで1回だけ発生することを保証できる場合は、上記を言い換えることができます。

nlist一意のアイテムのリストのリストを指定すると、合計回数だけ発生する場合にのみ、すべてのリストに値が発生します。

セットを使用して、リスト内のアイテムが一意であることを保証できるため、この後者の原則を単純なカウント戦略と組み合わせることができます。

>>> l = [[3,2,1], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]
>>> count = {}
>>> for i in itertools.chain.from_iterable(map(set, l)):
...     count[i] = count.get(i, 0) + 1
...     

これで、元のリストをフィルタリングするだけです。

>>> [i for i in l[0] if count[i] == len(l)]
[3, 2, 1]
于 2012-06-29T14:22:32.880 に答える
2

itertoolsを使用する別の方法は次のとおりです。

>>> import itertools
>>> L = [[3,2,1,4], [3,2,1,4,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]
>>> common_prefix = []
>>> for i in itertools.izip(*L):
...    if i.count(i[0]) == len(i):
...       common_prefix.append(i[0])
...    else:
...       break
... 
>>> common_prefix
[3, 2, 1]

しかし、それがどのように「pythonic」と見なされるかはわかりません。

于 2012-06-29T14:36:27.093 に答える
0

不一致が見つかるとすぐに早期に終了しないため、非効率的ですが、整頓されています。

([i for i,(j,k) in enumerate(zip(a,b)) if j!=k] or [0])[0]
于 2014-09-19T18:46:33.453 に答える
0

ジェネレータ式とPython3の組み込みを使用した最新の垂直スキャンzipソリューション:

lst = [[3,2,1], [3,2,1,1,5], [3,2,1,8,9], [3,2,1,5,7,8,9]]

next(zip(*(x for x in zip(*lst) if len(set(x)) == 1)))
# (3, 2, 1)

関連するLeetcodeの問題-最長の共通プレフィックスも参照してください。

于 2018-08-16T23:37:07.137 に答える