2013-07-01 3 views
0

У меня есть куча строк в тексте с именами и команд в этом формате:Совокупные наборы по клавишам с defaultdict питона

Team (year)|Surname1, Name1 

например

Yankees (1993)|Abbot, Jim 
Yankees (1994)|Abbot, Jim 
Yankees (1993)|Assenmacher, Paul 
Yankees (2000)|Buddies, Mike 
Yankees (2000)|Canseco, Jose 

и т. Д. Несколько лет и несколько команд. Я хотел бы объединить имена игроков в соответствии с комбинацией (год), удаляя любые дублированные имена (может случиться, что в исходной базе данных имеется некоторая избыточная информация). В примере, мой вывод должен быть:

Yankees (1993)|Abbot, Jim|Assenmacher, Paul 
Yankees (1994)|Abbot, Jim 
Yankees (2000)|Buddies, Mike|Canseco, Jose 

Я написал этот код до сих пор:

file_in = open('filein.txt') 
file_out = open('fileout.txt', 'w+') 

from collections import defaultdict 
teams = defaultdict(set) 

for line in file_in: 
    items = [entry.strip() for entry in line.split('|') if entry]  
    team = items[0] 
    name = items[1] 
    teams[team].add(name) 

Я в конечном итоге с большим словарем, образуемой ключами (название команды и год) и наборы значений. Но я точно не знаю, как это сделать.

Я также смог бы сравнить мои последние наборы значений (например, сколько игроков имеет команду Янки 1993 и 1994 годов?). Как я могу это сделать?

любая помощь

ответ

0

Вы можете использовать кортеж в качестве ключа здесь, например, для. ('Yankees', '1994'):

from collections import defaultdict 
dic = defaultdict(list) 
with open('abc') as f: 
    for line in f: 
     key,val = line.split('|') 
     keys = tuple(x.strip('()') for x in key.split()) 
     vals = [x.strip() for x in val.split(', ')] 
     dic[keys].append(vals) 
print dic 
for k,v in dic.iteritems(): 
    print "{}({})|{}".format(k[0],k[1],"|".join([", ".join(x) for x in v])) 

Выход:

defaultdict(<type 'list'>, 
{('Yankees', '1994'): [['Abbot', 'Jim']], 
('Yankees', '2000'): [['Buddies', 'Mike'], ['Canseco', 'Jose']], 
('Yankees', '1993'): [['Abbot', 'Jim'], ['Assenmacher', 'Paul']]}) 

Yankees(1994)|Abbot, Jim 
Yankees(2000)|Buddies, Mike|Canseco, Jose 
Yankees(1993)|Abbot, Jim|Assenmacher, Paul 
+0

На самом деле я хотел бы быть в состоянии обработать имя и год как неразрывный пункт и разделить каждую строку только 2 части (с «|»). Проблема в том, что база данных может также содержать другие строки в круглых скобках, и я думаю, что я мог бы повредить вещи, используя() как разделитель. – user2447387

+0

@ user2447387 Если вы не знаете, что будет содержать(), как бы вы сравнили два ключа? Пожалуйста, напишите лучший пример, который содержит такие строки. –

+0

К сожалению, исходные данные были довольно перепутаны. Я пытался его очистить, и я бы сказал, что в 95% случаев структура строк всегда одинакова (как в примере). Однако могут быть некоторые исключения, и я буду иметь дело с ними, как только большинство строк будет агрегировано. Вот почему я считаю, что с моей точки зрения безопаснее иметь дело только с двумя подстроками (разделенными «|») – user2447387

Смежные вопросы