Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无嵌套循环的邻接矩阵_Python_Algorithm - Fatal编程技术网

Python 无嵌套循环的邻接矩阵

Python 无嵌套循环的邻接矩阵,python,algorithm,Python,Algorithm,我试图为一组团队成员创建一个邻接矩阵。我已经像这样存储了比赛细节- x={'match1':[1,2,3],'match2':[2,3,4],'match3':[3,4,5]} 在这里,每个关键字都有一个值列表,其中包含为那场比赛效力的队员 我试图创建一个邻接矩阵,显示每个队员与另一个队员的比赛次数 输出应该如下所示 1 2 3 4 5 1 1 1 1 0 0 2 1 2 2 1 0 3 1 2 3 2 1 4 0 1 2 2 1 5 0 0 1 1 1 (i,i)矩阵中的元素是该团

我试图为一组团队成员创建一个邻接矩阵。我已经像这样存储了比赛细节-

 x={'match1':[1,2,3],'match2':[2,3,4],'match3':[3,4,5]}
在这里,每个关键字都有一个值列表,其中包含为那场比赛效力的队员

我试图创建一个邻接矩阵,显示每个队员与另一个队员的比赛次数

输出应该如下所示

  1 2 3 4 5
1 1 1 1 0 0
2 1 2 2 1 0
3 1 2 3 2 1
4 0 1 2 2 1 
5 0 0 1 1 1
(i,i)
矩阵中的元素是该团队成员进行的比赛总数。我已经能够使用
计数器
正确计算值

from collections import defaultdict, Counter

if __name__=='__main__':
    x = {'match1': [1, 2, 3], 'match2': [2, 3, 4], 'match3': [3, 4, 5]}
    d = defaultdict(list)
    col_count = dict()
    for key, value in x.items():
        for i in value:
            d[i] += value
    for key, value in d.items():
        col_count[key] = Counter(d[key])
    print(col_count)
输出为:

{1: Counter({1: 1, 2: 1, 3: 1}), 2: Counter({2: 2, 3: 2, 1: 1, 4: 1}), 3: Counter({3: 3, 2: 2, 4: 2, 1: 1, 5: 1}), 4: Counter({3: 2, 4: 2, 2: 1, 5: 1}), 5: Counter({3: 1, 4: 1, 5: 1})}
鉴于
x
字典将包含大量键,并且每个键都有一个包含许多元素的列表,我希望避免使用嵌套的
for
循环

是否可以将匹配细节存储为任何其他数据类型,以便后续计算不需要嵌套循环


如果字典是最好的方法,是否可以用其他方法计算矩阵?

在不修改输入和输出格式的情况下,我不知道如何避免嵌套循环,因为您有按匹配分组的信息,并且希望按播放器提取。实际上,您可以通过在嵌套循环中创建
计数器来避免最后一个循环:

from collections import defaultdict, Counter

if __name__=='__main__':
    x = {'match1': [1, 2, 3], 'match2': [2, 3, 4], 'match3': [3, 4, 5]}
    d = defaultdict(Counter)
    for key, value in x.items():
        for i in value:
            d[i].update(value)
    print(d)
如果可以修改输入,您可以进行如下操作:

from collections import Counter

if __name__=='__main__':
    x = {1: [{1, 2, 3}], 2: [{1, 2, 3}, {2, 3, 4}], 3: [{1, 2, 3}, {2, 3, 4}, {3, 4, 5}], 4: [{2, 3, 4}, {3, 4, 5}], 5: [{3, 4, 5}]}
    d = {player: Counter([p for match in matches for p in match]) for player, matches in x.items()}
    print(d)
在这里,您将嵌套循环替换为dict和列表理解,这应该更有效。球员和比赛可能不是
int
s和
list
s的
int
s,因此这可以做得更可编辑一些。例如:

from collections import defaultdict, Counter

def printMatrix(matrix):
    print(' '.join(['   |'] + list(map(str, matrix.keys()))))
    print('---+-' + '-'*len(matrix)*2)
    for row, values in matrix.items():
        fmt = ' {row} |'
        for col in matrix.keys():
            fmt += ' {values[' + str(col) + ']}'
        print(fmt.format(row=row, values=values))

class Entity:
    def __init__(self):
        self._id = None

    @classmethod
    def register(cls, value):
        if value in cls.ids:
            raise ValueError("The provided ID is already in use")
        cls.ids.add(value)

    @classmethod
    def unregister(cls, value):
        if value is not None:
            cls.ids.remove(value)

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, value):
        if value == self.id:
            return
        self.register(value)
        self.unregister(self.id)
        self._id = value

class Player(Entity):
    ids = set()

    def __init__(self, pid):
        super().__init__()
        self.id = pid
        self.__matches = set()

    def __repr__(self):
        return 'Player<{}>'.format(self.id)

    @property
    def matches(self):
        return set(self.__matches)

    def inscribe(self, match):
        if match not in self.__matches:
            self.__matches.add(match)

    def delist(self, match):
        self.__matches.remove(match)

class Match(Entity):
    ids = set()

    def __init__(self, mid, players):
        super().__init__()
        self.id = mid
        self.__players = set()
        self.players = players
        for player in players:
            player.inscribe(self)

    def __repr__(self):
        return 'Match<{}>'.format(self.id)

    @property
    def players(self):
        return set(self.__players)

    @players.setter
    def players(self, value):
        for player in self.__players:
            player.delist(self)
        self.__players = set(value)
        for player in self.__players:
            player.inscribe(self)

if __name__=='__main__':
    players = [Player(i) for i in range(1, 6)]
    matches = [Match(i, {players[i-1], players[i], players[i+1]}) for i in range(1, 4)]

    for player in players:
        print(player, player.matches)

    for match in matches:
        print(match, match.players)

    d = {player.id: Counter([p.id for match in player.matches for p in match.players]) for player in players}
    printMatrix(d)
从集合导入defaultdict,计数器
def打印矩阵(矩阵):
打印(“”.join(['|']+list(map(str,matrix.keys())))
打印('-+-'+'-'*len(矩阵)*2)
对于行,矩阵.items()中的值:
fmt='{row}|'
对于矩阵.keys()中的列:
fmt+='{values['+str(col)+']}'
打印(格式(行=行,值=值))
类实体:
定义初始化(自):
self.\u id=None
@类方法
def寄存器(cls,值):
如果cls.ids中的值为:
raise VALUERROR(“提供的ID已在使用”)
cls.ids.add(值)
@类方法
def注销(cls,值):
如果值不是“无”:
cls.ids.remove(值)
@财产
def id(自身):
返回自我。\u id
@id设置器
def id(自身,值):
如果值==self.id:
返回
自寄存器(值)
self.unregister(self.id)
self.\u id=值
职业玩家(实体):
ids=set()
定义初始化(自,pid):
super()。\uuuu init\uuuuu()
self.id=pid
self.\uuu matches=set()
定义报告(自我):
返回“Player”。格式(self.id)
@财产
def匹配(自我):
返回集(自匹配)
def题字(自我,匹配):
如果匹配不在self中。\u匹配:
self.\u匹配。添加(匹配)
def退市(自我、匹配):
自匹配。删除(匹配)
类别匹配(实体):
ids=set()
定义初始(自我、中场、球员):
super()。\uuuu init\uuuuu()
self.id=mid
self.\uu players=set()
self.players=玩家
对于玩家中的玩家:
玩家。题写(自我)
定义报告(自我):
返回“匹配”。格式(self.id)
@财产
def玩家(自我):
返回集(自选球员)
@二传手
def玩家(自我、价值):
对于自己的玩家。\u玩家:
球员退市(自我)
self.\uu players=set(值)
对于自己的玩家。\u玩家:
玩家。题写(自我)
如果“名称”=“\uuuuuuuu主要”:
players=[范围(1,6)内的Player(i)代表i]
matches=[Match(i,{players[i-1],players[i],players[i+1]})为范围(1,4)内的i进行匹配]
对于玩家中的玩家:
打印(球员,球员,比赛)
对于匹配中的匹配:
打印(比赛,比赛,球员)
d={player.id:Counter([p.id代表player中的match.matches代表p代表match.players])代表player中的player}
打印矩阵(d)
printMatrix()
函数只是我用来将输出漂亮地打印到屏幕上的一个助手

实体
类避免了
玩家
匹配
类都需要的重复代码,因为它们都有唯一的ID。构造函数创建一个空的
\u id
属性。
register()
unregister()
方法处理从类属性
IDs
添加和删除id。它还声明了带有getter和setter的
id
属性。子类只需要在构造函数中调用
super()。\uuuu init\uuuu()
,并在想要强制ID唯一性的级别创建
ids
class属性,就像
Player
Match
所做的那样

Player
类还具有
matches
实例只读属性,该属性分别由
inscribe()
delist()方法填充和取消填充。
Match
类具有带有getter和setter方法的
players
属性

首先,使用两种列表理解创建
玩家
比赛
(请记住,列表从位置0开始,因此ID为1的
玩家
位于
玩家[0]
)并打印其对应关系(他们为玩家和参与比赛的玩家播放的比赛)


由于两者都保留了对另一种类型的引用,我们可以获得构建
计数器
指令所需的所有信息,您刚刚从
玩家那里请求

我认为矩阵中有一个输入错误,
5
应该是
1
,不应该吗?错误已经纠正了。row=2 path=2 result=2是什么意思?玩家2打了两场比赛。我想你不能