3

番号が指定されていない int リストがあります。リスト内の特定の値に一致する 2 つの整数の違いを見つけたいと思います。

from itertools import combinations

#Example of a list
intList = [3, 6, 2, 7, 1]
diffList = [abs(a -b) for a, b in combinations(intList, 2)]

#Given if difference = 2    
print diffList.count(2)

コード スニペットは機能しましたが、より大きなリストを指定すると、MemoryError が発生します。コードに何か問題があるのか​​、それともエラーがハードウェアの制限によるものなのか、誰か教えてもらえますか?

4

3 に答える 3

4

「より大きなリスト」とは正確にどれくらいの大きさですか?len(intList)がの場合n、 (一度に 2 つ取られるものの組み合わせの数) にlen(diffList)なります。十分な大きさの場合、これはすべてのメモリを消費します。n*(n-1)//2nn

値 2 だけを気にする場合は、

print sum(abs(a-b) == 2 for a, b in combinations(intList, 2))

サイズに関係なくメモリをほとんど消費しない方法の 1 つintListです。ただし、それでもの 2 乗に比例する時間len(intList)がかかります。

于 2013-09-20T00:23:37.280 に答える
3

このコードを使用して問題を解決できます。

result = 0
for a, b in combinations(intList, 2):
    if abs(a - b) == 2:
        result += 1
print result

したがって、問題はハードウェアの制限だけではなく、ハードウェアの制限と悪いコードです。

于 2013-09-20T00:24:05.350 に答える
3

リスト内包表記でリストを作成し、そのcountメソッドを呼び出しました。icount代わりに、ジェネレータ式でイテレータを作成し、イテラブルを取る関数を呼び出します。

diffs = (abs(a -b) for a, b in combinations(intList, 2))
print icount(diffs, 2)

元のコードとほぼ同じですが、余分なメモリは使用しません。


もちろんそのicount関数は存在しませんが、自分で書けるはずです。

def icount(iterable, value):
    result = 0
    for element in iterable:
        if element == value:
            result += 1
    return result

…または…</p>

def ilen(iterable):
    return sum(1 for _ in iterable)
def icount(iterable, value):
    filtered = (elem for elem in iterable if elem == value)
    return ilen(filtered)

…または…</p>

def icount(iterable, value):
    return sum(elem == value for elem in iterable)

…または ( itertools レシピを使用) …</p>

def icount(iterable, value):
    return quantify(iterable, lambda elem: elem == value)

必要に応じて、式をicount関数にマージして、すべてを 1 行で実行すると、Tim Peters の答えが正確に得られます。

于 2013-09-20T01:15:30.623 に答える