将文件的部分解释为节点和边

2024-09-21 20:12:21 发布

您现在位置:Python中文网/ 问答频道 /正文

你的程序应该输出一个文件调用图.txt两部分采用以下结构。这两部分用一条空线隔开。你知道吗

第一部分:节点

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

第二部分:边缘

每一条边在一行中显示如下:起点编号、终点编号、权重;其中起点编号和终点编号是标识文件第一部分中节点的编号。你知道吗

一个例子调用图.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

现在我的问题是:我正试图找出如何完成第二部分,我只是卡住了。我的问题是,每个唯一的数字都是一个节点,我给它分配一个从1到有多少个唯一数字的数字。我想要的是,当一个号码呼叫另一个号码时,它会打印出两个节点,然后也会显示它们之间通话的时间,并对每个号码都这样做。任何建议都将不胜感激。你知道吗

这是我到目前为止的代码,它回答了第一部分。你知道吗

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)

链接到呼叫.txt文件:http://pastebin.com/RSMnXDtq

链接到客户.txt文件:http://pastebin.com/xMx15nCS


Tags: 文件intxt节点time电话号码数字open
2条回答

使用迭代器it分两步读取文件。 一旦你得到一个空行,停止第一个循环。 这里的iter将指向下一行,允许您在break指令之后继续迭代。你知道吗

此外,我还添加了namedtuple类型的用法,它似乎很适合您的任务。你知道吗

from collections import namedtuple

Call = namedtuple('Call', ['number', 'phone_number', 'name', 'city', 'total_time_spent'])

with open('out.txt', 'r') as f:
    it = iter(f)
    calls = []
    for line in it:
        line = line.strip()
        if not line:
            break
        call = Call(*line.split(', '))
        calls.append(call)


    for line in it:
        # code is similar

我想,你可以自己写第二部分)

这个问题很复杂,编码前需要一个计划。首先,将电话号码映射到序列号只是一个外围麻烦。它可以在输入或输出上完成。在开发求和问题的解决方案时,让我们忘掉序列号。你知道吗

我假设呼叫.txt由“src dst secs”组成。问题是计算每个(src,dst)对的小计,然后计算每个src的总计。标准的数据库报告方法是按src和dst对调用进行排序,然后计算并打印每个src和dst对的小计,其中src的行后跟src的总计。问题发起人抛出了一个曲线球,要求在小计之前打印所有的总数。因此,您首先计算总计而不计算小计。你知道吗

这里可以使用排序和扫描方法,保存小计以便以后打印。你试试这个主意不错。但是我们可以通过使用dict将每个src映射到dict来跳过排序,dict将每个dst映射到来自该src的调用的秒小计。你知道吗

subs = {}
with open(calls.txt) as f:
    for line in f:
        src, dst, sec = line.split()
        sub = subs.get(src, {})
        sub.get(dst, 0) += 1

使用.get(key,default\u value)比使用那些条件语句要容易得多。或者sub可以预先加载(number,{})对。当填写subs时,它将类似于以下内容(电话号码按顺序排列为2、7和4):

{7801234567: {7801236789: 40425,
              7803214567: 21618,
              ...
             },
 7801236789: (7803214567: 32851,
              ...},
 ...
}

编辑:修改和扩展以下内容。。你知道吗

这样,就很容易计算每个src的总数。下面的,未经测试,如上所述,应该工作。你知道吗

totals = {key: sum(dstdict.values()) for key, dstdict in subs.items()} 

创建另一个将电话号码映射到序列号的dict。如果每个人都打电话,并且是subs中的一个键,那么下面的代码就起作用了。你知道吗

seqs = {phone: i for i, phone in subs}

否则,在读取电话号码文件时将其扩充或创建。你知道吗

相关问题 更多 >