1

さまざまなサイズのデータ​​セットを使用して、かなり頻繁に使用するスクリプトを作成しています。Python では簡単に実行できないいくつかの比較を行う必要があります。

複数のリスト (約 20 以上ですが、例とテストの目的で 3 つに減らしました) があり、すべて同じ数の整数項目が特定の順序で並んでいます。すべてのリストの同じ位置にあるアイテムを比較して違いを見つけたい。定義された数のリストの場合、これは簡単です。

a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
b = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 4, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
c = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

for x,y,z in zip(a,b,c):
    if x != y != z:
        print x, y, z

そのループを関数でラップしようとしたので、引数の数はさまざまですが、行き詰まりました。

def compare(*args):
    for x in zip(args):
        ???

最後のスクリプトでは、複数の単一のリストではなく、1 つのリストのリストにまとめてあります。それは役に立ちますか?リストのリストをループすると、一度にすべてのリストを取得することはできません...

function を忘れてください。それはより大きなスクリプトの一部になり、さまざまな引数を定義するのが難しすぎるため、とにかくあまり役​​に立ちません。現在、一度に 2 つのリストを比較し、同一のものを保存しています。そうすれば、後でリスト全体からそれらすべてを簡単に削除して、一意のものだけを保持できます。

l_o_l = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 4, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

for i in range(0, (len(l_o_l)-1)):
    for j in range((i+1), len(l_o_l)):
        if l_o_l[i] == l_o_l[j]:
            duplicates.append(key_list[i])
            duplicates.append(key_list[j])
dup = list(set(duplicates))
uniques = [x for x in key_list if x not in dup]

key_list には、辞書から取得したリストの識別子が含まれています。

改善のための提案はありますか?

4

5 に答える 5

3

たぶん、このようなもの

def compare(*args):
    for things in zip(*args):
        yield all(x == things[0] for x in things)

その後、このように使用できます

a = range(10)
b = range(10)
c = range(10)
d = range(11, 20)

for match in compare(a,b,c):
    print match

for match in compare(a,b,c,d):
    print match

これはあなたの例を使用したデモです(ジェネレーターなので、反復処理するか、を使用して使い果たす必要がありますlist

a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
b = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 4, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
c = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

print list(compare(a,b,c))
于 2013-02-07T09:18:15.227 に答える
1
def compare(*args):
    for x in zip(args):
        values_list = list(x[0]) # x[0] because x is a tuple
        different_values = set(values_list) # a set does not contain identical values
        if len(different_values) != 1: # if you have more than 1 value you have different values in your list
            print 'different values', values_list

あなたにあげる

a = [0, 0, 1]
b = [0, 1, 1]
c = [1, 1, 1]
compare(a, b, c)
>>> different values [0, 0, 1]
>>> different values [0, 1, 1]
于 2013-02-07T10:21:12.790 に答える
0

リストが例のリストに似ていると仮定すると、次を使用します。

def compare(*args):
    for x in zip(args):
        if min(x) != max(x):
             print x
于 2013-02-07T10:19:25.400 に答える
0
def compare(elements):
    return len(set(elements)) == bool(elements)

すべてのリストが同じかどうかを知りたい場合は、次のように簡単に実行できます。

all(compare(elements) for elements in zip(the_lists))

別の方法として、 を に変換して、listそこで使用することもtupleできます。set

len(set(tuple(the_list) for the_list in the_lists) == bool(the_lists)

単純に重複を削除したい場合は、これの方が高速です。

the_lists = [list(elem) for elem in set(tuple(the_list) for the_list in the_lists)]

使用例:

>>> a = range(100)
>>> b = range(100, 200)
>>> c = range(200, 300)
>>> d = a[:]
>>> e = b[:]
>>> the_lists = [a,b,c,d,e]
>>> the_lists2 = [list(elem) for elem in set(tuple(the_list) for the_list in the_lists)]
>>> [a,b,c] == sorted(the_lists2)  #order is not maintained by set
True

かなり速いようです:

>>> timeit.timeit('[list(elem) for elem in set(tuple(the_list) for the_list in the_lists)]', 'from __main__ import the_lists', number=1000000)
7.949447154998779

100万回の実行で8秒未満。the_lists(以前と同じものはどこにありますか。)

編集: 重複したものだけを削除したい場合、list私が考えることができる最も簡単なアルゴリズムは、リストのリストをソートして使用することitertools.groupbyです:

>>> a = range(100)
>>> b = range(100,200)
>>> c = range(200,300)
>>> d = a[:]
>>> e = b[:]
>>> the_lists = [a,b,c,d,e]
>>> the_lists.sort()
>>> import itertools as it
>>> for key, group in it.groupby(the_lists):
...     if len(list(group)) == 1:
...             print key
... 
[200, 201, 202, ..., 297, 298, 299]
于 2013-02-07T10:12:31.183 に答える
-1

*args と zip を賢くしようとすると、問題が混乱するだけだと思います。私はそれを次のように書きます:

def compare(list_of_lists):
    # assuming not an empty data set
    inner_len = len(list_of_lists[0])
    for index in range(inner_len):
        expected = list_of_lists[0][index]
        for inner_list in list_of_lists:
            if inner_list[index] != expected:
                # report difference at this index
于 2013-02-07T10:22:25.867 に答える