0

Facebookのような通知を作成しようとしています。すべて正常に動作しますが、重複があります。たとえば、action = like、url = post/1 status = 1 のすべての通知を受け取りたい - 未読で、action と url が同じ重複を排除します。以下のコードを見つけることができます。このようなエラーがあります。

エラー: '範囲外のリスト インデックス'

if n_dup[i]['url'] == n_dup[j]['url'] and n_dup[i]['action'] == n_dup[j]

def recieve_notification(request):
    t = loader.get_template('notifications.html')
    nots = Notification.objects.filter(recipent=request.user, status=1, pub_date__gte=datetime.datetime.now()-datetime.timedelta(days=3))
    n_dup = [] #list of notifications with duplicates
    for n in nots:
        n_dup.append({'id':n.id, 'url':n.url, 'action':n.action})

    i = len(n_dup)-1
    j = len(n_dup)-1    
    while j>=0:
        while i>=0: 
            if n_dup[i]['url'] == n_dup[j]['url'] and n_dup[i]['action'] == n_dup[j]['action'] and i is not j:  
                del n_dup[i]
            i-=1
        j-=1
        out_n = []      
        for n in n_dup:
            n_id = n['id']  
        out_n.append(Notification.objects.get(id=n_id)) 

    c = RequestContext(request, {'notifications':out_n, 'notifications_count':len(out_n)})
    return HttpResponse(t.render(c))`

たぶん、あなたはこれらすべてのものをコーディングするためのより良い方法を知っていますか?

4

1 に答える 1

4

両方のループの最初の反復では、j == i == len(n_dup)-1、そうn_dup[i] == n_dup[j]. 重複と見なされ、削除されます。2 回目の反復では、n_dub[len(n_dup)-1]削除したため、もう存在しないものにアクセスしようとします。


別のアプローチを提案する場合は、怠惰になり、Python に重複検出を実行させます。

class Notification:
    def __init__(self, id, url, action):
        self.id = id
        self.url = url
        self.action = action

    def __eq__(self, other):
        return self.url == other.url and self.action == other.action

    def __hash__(self):
        return hash(self.url) ^ hash(self.action)


unique_notifications = {Notification(n.id, n.url, n.action) for n in nots}

それを比較してハッシュを計算する方法で通知オブジェクトを定義し(これはセットに入れるために必要です)、通知のセットを作成します。セットには重複が含まれないため、セットを反復処理できるようになりました!

このメソッドを通知オブジェクトに追加して、直接使用することもできます。次に、次のように記述します。

out_n = set(Notification.objects.filter(...))

ボーナス:重複を削除するためにセットで使用されるアルゴリズムは、使用しているアルゴリズムよりもはるかに効率的です。

于 2012-07-09T14:51:45.227 に答える