查找两个不同大小的无序 Python 列表的匹配元素

问题描述

我收到此错误import suspengine app = suspengine iden = 0 players = [] @app.channel("connect") def connect(c,addr): global iden global players player_id = iden app.savevariable("id",player_id,c) for p in players: temp = p temp['msgid'] = 0 app.emit("position",temp,c) players.append({'id': player_id,'x': 200,'y': 200}) app.broadcast("position",{'id': player_id,'y': 200,'msgid': 0}) print("- Player connected #" + str(app.callvariable("id",c))) iden += 1 @app.channel("disconnect") def disconnect(c,addr): global players player_id = app.callvariable("id",c) for p in players: if p['id'] == player_id: players.remove(p) app.broadcast('position','msgid': 2}) print("- Player disconnected #" + str(player_id)) app.server("0.0.0.0",5000) 。我正在做一个关于二叉搜索树的作业,我把树放到列表中,我只是想比较这两个列表:

import socket
import threading
import json

userdata = {}
clientlist = []
userevents = {}
userdata = {}
use = {}
prev = {}
limit = False
defaultlimit = 4096
debug = False
splitter = "[{//V//}]"


def savevariable(name,data,client):
    global userdata
    userdata[str(client)][name] = data


def callvariable(name,client):
    global userdata
    if name in userdata[str(client)]:
        return userdata[str(client)][name]
    else:
        return None


def emit(event,message,client):
    global splitter
    tempdata = {}
    tempdata[event] = message
    tempdata['identify'] = event
    message = json.dumps(tempdata) + splitter
    client.send(message.encode('utf-8'))


def broadcast(event,message):
    global clientlist
    global splitter
    tempdata = {}
    tempdata[event] = message
    tempdata['identify'] = event
    message = json.dumps(tempdata) + splitter
    for c in clientlist:
        c.send(message.encode('utf-8'))


def disconnect(client):
    client.close()


def handleclient(c,addr):
    global clientlist
    global userevents
    global splitter
    global use
    global prev
    global limit
    global defaultlimit
    global debug
    while True:
        try:
            data = c.recv(defaultlimit)
            if not data:
                clientlist.remove(c)
                if 'disconnect' in use:
                    use['disconnect'](c,addr)
                break
        except:
            #PROBLEM LIES HERE (c (client) doesn't exist in clientlist)
            print(str(c))
            clientlist.remove(c)
            if 'disconnect' in use:
                use['disconnect'](c,addr)
            break
        stuff = []
        try:
            data = data.decode('utf-8')

            if not limit:
                data = prev[str(c)] + data
                stuff = data.split(splitter)
                if len(stuff) > 1:
                    prev[str(c)] = ""
                if not "" in stuff:
                    prev[str(c)] = stuff[len(stuff) - 1]
                    del stuff[len(stuff) - 1]
                    if debug:
                        print("Your packet is bigger than the default size limit")
                stuff.remove("")
            else:
                stuff = data.split(splitter)
                stuff.remove("")
        except:
            pass
        for s in stuff:
            # print(stuff)
            tempdat = json.loads(s)
            for keys in tempdat.keys():
                if keys in use:
                    threading.Thread(target=use[keys],args=[c,addr,tempdat[keys]]).start()
                    # print(userevents)


# noinspection PyInterpreter
def server(host,port,**kwargs):
    s = socket.socket()
    s.bind((host,port))
    # Variables for kwargs
    slots = 20
    global limit
    global debug
    global defaultlimit
    #
    for stuff in kwargs.items():
        if stuff[0] == 'debug':
            debug = stuff[1]
            if debug:
                print('Debug Enabled')
        if stuff[0] == 'slots':
            slots = stuff[1]
            if debug:
                print('Your server can take ' + str(stuff[1]) + " connections.")
        if stuff[0] == 'limit':
            limit = stuff[1]
            if debug and limit == False:
                print('You have removed the limit on how big your packets can be')
        if stuff[0] == 'defaultlimit':
            defaultlimit = stuff[1]
            if debug:
                print('Your limit to how big a packet can be is ' + str(stuff[1]) + " bytes.")

    s.listen(slots)
    global clientlist
    global use
    global userdata
    global prev
    print("Server running!")
    while True:
        c,addr = s.accept()
        clientlist.append(c)
        threading.Thread(target=handleclient,addr]).start()
        userdata[str(c)] = {}
        prev[str(c)] = ""
        print(str(addr[0]) + " Connected To The Server From Port " + str(addr[1]))
        print(str(c))
        if 'connect' in use:
            use['connect'](c,addr)

我假设嵌套的 for 循环应该完全迭代每个循环中的所有元素,因此 index out of range,in if largerList[j] == smallerList[i] 是较小的列表,因此 def matchList(largerList,smallerList) : matches = [] for i in smallerList: for j in largerList: if largerList[j] == smallerList[i] : matches[i] = smallerList[i] return matches 不会使 smallerList 越界。内部 for 循环应该完全遍历所有较大的列表,将每个值与较小列表的每个元素进行比较。为什么它不起作用?

解决方法

如果 matches[i] 中不存在该索引,则不能使用 matches 设置列表值。

尝试附加:

把这个matches[i] = smallerList[i]改成这个matches = matches.append(smallerList[i])

,

试图在这样的列表中查找匹配元素是相当低效的。你可以改进的一件事是使用列表理解:

matches = [i for i in largerList if i in smallerList]

但数学上更明智的方法仍然是意识到我们有两组元素,我们想要找到两组元素的交集,这样我们就可以写出类似的东西:

matches = set(largerList).intersection(smallerList)