Python 将文件的某些部分用作节点

Python 将文件的某些部分用作节点,python,python-3.x,dictionary,tuples,Python,Python 3.x,Dictionary,Tuples,第一部分:节点 每个节点显示在一行中,如下所示:号码、电话号码、姓名、城市、花费的总时间;其中,number是从1开始标识节点的序列号。Total time Speed是由电话号码发起的呼叫的总秒数 2, 7801234567, Ameneh Gholipour Shahraki, Hinton, 198473 7, 7801236789, Stuart Johnson, Saint Albert, 64399 4, 7803214567, Md Toukir Imam, Sherwood Pa

第一部分:节点

每个节点显示在一行中,如下所示:号码、电话号码、姓名、城市、花费的总时间;其中,number是从1开始标识节点的序列号。Total time Speed是由电话号码发起的呼叫的总秒数

2, 7801234567, Ameneh Gholipour Shahraki, Hinton, 198473
7, 7801236789, Stuart Johnson, Saint Albert, 64399
4, 7803214567, Md Toukir Imam, Sherwood Park, 179532
8, 7804321098, Hamman Samuel, Stony Plain, 57909
1, 7804922860, Osmar Zaiane, Edmonton, 250068
5, 7807890123, Elham Ahmadi, Devon, 129370
9, 7808765432, Amir Hossein Faghih Dinevari, Beaumont, 62552
6, 7808907654, Weifeng Chen, Spruce Grove, 121726
3, 7809876543, Farrukh Ahmed, Edson, 190211

2, 7, 40425
2, 4, 21618
2, 8, 34186
2, 1, 34291
2, 5, 24286
2, 9, 67786
2, 6, 21983
2, 3, 35614
7, 4, 32851
7, 8, 27293
7, 1, 45367
第二部分:边缘

每条边在一行中显示如下:起点编号、终点编号、重量;其中,number origin和destination是标识文件第一部分中节点的编号

callgraph.txt文件的示例如下所示。请注意,节点是按电话号码排序的

2, 7801234567, Ameneh Gholipour Shahraki, Hinton, 198473
7, 7801236789, Stuart Johnson, Saint Albert, 64399
4, 7803214567, Md Toukir Imam, Sherwood Park, 179532
8, 7804321098, Hamman Samuel, Stony Plain, 57909
1, 7804922860, Osmar Zaiane, Edmonton, 250068
5, 7807890123, Elham Ahmadi, Devon, 129370
9, 7808765432, Amir Hossein Faghih Dinevari, Beaumont, 62552
6, 7808907654, Weifeng Chen, Spruce Grove, 121726
3, 7809876543, Farrukh Ahmed, Edson, 190211

2, 7, 40425
2, 4, 21618
2, 8, 34186
2, 1, 34291
2, 5, 24286
2, 9, 67786
2, 6, 21983
2, 3, 35614
7, 4, 32851
7, 8, 27293
7, 1, 45367
现在我轻松完成了第一部分,如图所示:

customers=open('customers.txt','r')
    calls=open('calls.txt.','r')
    nodes= {}
    name={}
    city={}
    total_spent_time={}
    with open("customers.txt") as fp:
        for line in fp:
            number = line.split(";")[0]
            if number not in nodes:
                nodes[number] = len(nodes) + 1
            rows=line.split(";")
            name[rows[0]]=rows[1]
            city[rows[0]]=rows[2].strip("\n")
    with open("calls.txt") as fp2:    
        for lines in fp2:
            rows2=lines.split(";")
            if rows2[1] not in total_spent_time:
                total_spent_time[rows2[1]]=int(rows2[3])
            elif rows2[1]  in total_spent_time:
                total_spent_time[rows2[1]]+=int(rows2[3])
        print(total_spent_time)
但这是第二部分,我有最大的麻烦;例如,我必须为每个唯一的电话#分配一个节点号,然后如示例文件所示,计算每个节点与另一个节点通话的时间,依此类推

我从中获得唯一编号的文件如下:

包含这些号码之间数千次呼叫的文件如下:

其中calls.txt的第二行是发起者#,第三行是接收者#,第四行是这两个数字之间通话的总秒数

如何分配节点,计算每个数字之间的总时间,同时将它们用作节点

编辑:我想在呼叫者和接收者之间建立一个元组,结果成功了!但是现在我需要给它们分配节点号,我该怎么做呢

我补充说:

nodes_g={}
    with open("calls.txt") as fp3:
        for line in fp3:
            rows3=line.split(";")
            x,node1,node2,sec,y=line.split(";")
            if node1 not in nodes_g:
                nodes_g[node1]=node2
    print(nodes_g)
EDIT2:尝试将“节点”字典与另一个字典组合,以计算每个数字之间的总次数;不顺利,因为我收到一个错误,说python中的字典是不可损坏的。有人能告诉我一个解决办法吗

nodes_g={}
complete={}
with open("calls.txt") as fp3:
    for line in fp3:
        rows3=line.split(";")
        x,node1,node2,sec,y=line.split(";")
        if node1 not in nodes_g:
            nodes_g[node1]=node2
        else:
            nodes_g[node1]=node2
        for k,v in nodes_g.items():
            if node1 in nodes_g and node1!=node2:
                nodes_g[node1]=node2
        for k,v in nodes_g.items():
            if node1 and node2 in nodes_g:
                complete[nodes_g]=sec
            else:
                complete[nodes_g]+=sec

print(complete)
编辑3: 我尝试使用嵌套在dict中的元组,但出于某种原因,它没有添加值,而只是用下一行的值替换它,而没有添加它们

nodes_g={}
complete={}
with open("calls.txt") as fp3:
    for line in fp3:
        rows3=line.split(";")
        x,node1,node2,sec,y=line.split(";")
        if node1 not in nodes_g:
            nodes_g[node1,node2]=int(sec)
        if node1 in nodes_g and node2 in nodes_g:
            nodes_g[node1,node2]+=int(sec)
        print(nodes_g)



print(nodes_g)

如果您想要的是示例文件第二部分第一行中每个不同(目的地、收件人)对(2,7…)的总时间。。。然后我将创建一个字典,元组((2,7),(2,4),(2,8)等作为键,这些对话的总和(最初分别设置为(40425,21618,34186)作为值

换句话说,如果第一次调用是从第2点到第7点,持续40425秒(?),那么只需创建一个字典条目,该条目的键为
(2,7)
,初始值为
40425
。如果您遇到另一个从2到7的调用,则将其值添加到您的总和中(
my_report[(2,7)]+=XXXX

这将为从7到2的调用生成单独的条目。但是,您使用
tuple(排序((x,y))
作为键,在一个键下对两个方向的调用进行求和。换句话说,生成所有不同对的报告,而不管是哪一端发起了调用)

顺便说一句,如果*somekey*不在*mydict*中,您可以使用:
mydict[somekey]=mydict.get(somekey,0)减少
+value
…它将保持总和,并为以前不存在的任何键提供默认值零。这是一种常见的Pythonic微优化,可以将“EDIT3”代码末尾附近的四行替换为一行相对容易阅读的代码

我承认我没有信心正确解释您的意图。我注意到您的代码示例在上分裂,并且您的示例数据片段似乎是分隔的。我猜想这只是一些编辑/粘贴错误

#!/usr/bin/python
from __future__ import print_function # make example work for Python 2.7+ or 3.x
# ...
# ...
my_report = dict()
for line in fp3:
     try:
         row = tuple([int(x) for x in line.split(",", 3)])
     except ValueError, e:
         print("Corrupt data?: %s" % line, file=sys.stderr)
         continue
     key = row[:2]
     my_report[key] = my_report.get(key, 0) + row[3]
 # print(my_report)
 for node_pair, total in sorted(my_reports.iteritems()):
     print("%s: %d" % (node_pair, total))

(尽管您可能更喜欢输出的一些格式和排序;如图所示)。

您能更清楚地说明您的问题吗?我很困惑。电话是节点,电话之间的通话是节点之间的定向边。对吗?您为什么认为“现在我需要为它们分配节点号”?它们不是节点而是边。@Fumu7每个唯一的数字都是一个节点。我必须计算每个唯一数字之间的通话时间。有什么想法吗?一个起点和终点的元组可以用来识别它们之间的边。为什么你需要一个数字而不是起点和终点的元组?@Fumu7问题是这样问的要分配一个整数号码而不是只使用实际电话号码#。你能告诉我你的想法吗?在“callgraph.txt文件”的第一部分的每一行中,实际电话号码都分配了一个唯一的号码吗?我知道数字2是电话号码7801234567,数字7是电话号码7801236789,依此类推。元组(2,7)从您的示例中识别从电话号码7801234567到电话号码7801236789的一个边缘,一个对话。首先,我不知道有多少元组组合,因为该文件包含数千个调用;因此,为所有调用创建一个新的dict是不可能的。您想展示一下您在代码中的想法吗?我很高兴我很难理解你想要我回答什么。成千上万的成对元组(作为键)对于任何现代计算系统来说都不会是问题。即使是几百万也不会在现代桌面或服务器上占用过多的内存或CPU时间。我正在编辑我的帖子,以显示一个简单的代码示例,可以处理示例数据的第二部分。谢谢,我只是无法想象您所说的内容。代码未经测试。我试图合理地传达这个概念,而不是为您编写。我是用一个元组对作为dict中的键,然后在其上使用frozenset函数来解决这个问题的。谢谢您的帮助!:)