2016-01-15 2 views
2

У меня есть два больших списка.Извлечение (интервал) значений из нескольких словарей внутри одного большого списка и объединение их с соответствующими списками внутри другого большого списка

Первый - w_list; один большой список списков с (1) словом (например, «право»), (2) начальный id/tag (например, «# TWsp10») и (3) конечный id/tag (например, «# TWep10») , (Слова взяты из диалога между двумя ораторами). Начало w_list:

w_list = [['right', '#TWSp10', '#TWEp10'], ['_', '#TWSp11', '#TWEp11'], ['cough', '#TWSp12', '#TWEp12'], ['_', '#TWSp13', '#TWEp13'], ['go', '#TWSp14', '#TWEp14'], [...] , [...]] 

Второй список (t_list) - это один большой список словарей. Словари состоят из (1) ключа «xml: id» с соответствующим значением id/tag (например, «TWsp10», «TWep10»), эти значения напоминают начальный и конечный идентификаторы/теги в w_list, то есть число dicts в t_list в два раза больше количества списков в w_list), (2) ключ «интервал» со значением, представляющим время, в котором произошло слово в диалоге, и (3) ключ «с», который не имеет значения. Начало t_list:

t_list = [{'interval': '0', 'xml:id': 'TWSp10', 'since': '#TW0'}, {'interval': '0.2108', 'xml:id': 'TWEp10', 'since': '#TW0'}, {'interval': '0.2108', 'xml:id': 'TWSp11', 'since': '#TW0'}, {'interval': '0.7049', 'xml:id': 'TWEp11', 'since': '#TW0'}, {'interval': '0.7049', 'xml:id': 'TWSp12', 'since': '#TW0'}, {'interval': '0.9223', 'xml:id': 'TWEp12', 'since': '#TW0'}, {'interval': '0.9223', 'xml:id': 'TWSp13', 'since': '#TW0'}, {'interval': '1.6568', 'xml:id': 'TWEp13', 'since': '#TW0'}, {'interval': '1.6568', 'xml:id': 'TWSp14', 'since': '#TW0'}, {'interval': '1.7886', 'xml:id': 'TWEp14', 'since': '#TW0'}, {...} , {...}] 

Это пример вывода, что я хотел бы создать, какие-то намеки, чтобы получить меня на правильном пути/дорожки ?:

word: 'right' start: 0  end: 0.2108 
word: '_'  start: 0.2108 end: 0.1049 
word: 'cough' start: 0.7049 end: 0.9223 
'' 
'' 

, который является «похожи»:

'right' '#TWsp10': 0  '#TWsp10': 0.2108 
'_'  '#TWsp11': 0.2108 '#TWep11': 0.1049 
'cough' '#TWsp12': 0.7049 '#TWep12: 0.9223 
'' 
'' 

Создание слова, начальная и конечная строки с двоеточием определенно не проблема. Как извлечь значения интервалов из dicts (в t_list) и объединить их с их соответствующими/начальными идентификаторами/тегами из списков (в w_list).

Я ценю любые советы.

ответ

4

Сначала создайте словарь интервалов времени, с тегами, как ключи

time_dict = {i['xml:id'] : i['interval'] for i in t_list}

time_dict = 
{'TWEp10': '0.2108', 
'TWEp11': '0.7049', 
'TWEp12': '0.9223', 
'TWEp13': '1.6568', 
'TWEp14': '1.7886', 
'TWSp10': '0', 
'TWSp11': '0.2108', 
'TWSp12': '0.7049', 
'TWSp13': '0.9223', 
'TWSp14': '1.6568'} 

Тогда просто цикл по списку слов и получить времена

from collections import defaultdict 
res = defaultdict(list) 
for word, start, end in w_list: 
    res[word].append({'start':time_dict[start[1:]], 'end': time_dict[end[1:]] }) 

[1:] к удалите # из строки

Результат:

res = 
    { 
    "go": [ 
     { 
      "start": "1.6568", 
      "end": "1.7886" 
     } 
    ], 
    "cough": [ 
     { 
      "start": "0.7049", 
      "end": "0.9223" 
     } 
    ], 
    "right": [ 
     { 
      "start": "0", 
      "end": "0.2108" 
     } 
    ], 
    "_": [ 
     { 
      "start": "0.2108", 
      "end": "0.7049" 
     }, 
     { 
      "start": "0.9223", 
      "end": "1.6568" 
     } 
    ] 
} 

Edit:

Альтернатива для создания результатов от time_dict

from operator import itemgetter 
wlist2 = [(word, float(time_dict[start[1:]]), float(time_dict[end[1:]])) for word, start, end in w_list] 
wlist2.sort(key = itemgetter(1)) 

Десятиэтажное первых элементов в этом списке:

('right', 0.0, 0.2108) 
('_', 0.0, 1.0106) 
('_', 0.2108, 0.7049) 
('cough', 0.7049, 0.9223) 
('_', 0.9223, 1.6568) 
('nonvocal', 1.0106, 1.0688) 
('_', 1.0688, 2.2074) 
('go', 1.6568, 1.7886) 
('south', 1.7886, 2.229) 
('nonvocal', 2.2074, 2.4019) 
+0

@ K.Wine Некоторые из слов встречаются несколько раз? Поскольку dict использует слово в качестве ключа, любое дублирующее слово будет потеряно. Но res может быть преобразован в список, если это так. – M4rtini

+0

Фактически «-» произошло дважды в ваших данных примера. Поэтому я немного изменил сценарий. Можете ли вы добавить pastebin из полных данных или попытаться создать новый минимальный пример, где проблема присутствует? – M4rtini

+0

Я не могу найти ни одного слова, отсутствующего, есть ли какое-то конкретное слово, которое, как вы знаете, отсутствует? Вы снова проверили последнее обновление? – M4rtini

1

Вы можете сделать что-то например:

>>> w_list = [['right', '#TWSp10', '#TWEp10'], ['_', '#TWSp11', '#TWEp11'], ['cough', '#TWSp12', '#TWEp12'], ['_', '#TWSp13', '#TWEp13'], ['go', '#TWSp14', '#TWEp14']] 
>>> 
>>> t_list = [{'interval': '0', 'xml:id': 'TWSp10', 'since': '#TW0'}, {'interval': '0.2108', 'xml:id': 'TWEp10', 'since': '#TW0'}, {'interval': '0.2108', 'xml:id': 'TWSp11', 'since': '#TW0'}, {'interval': '0.7049', 'xml:id': 'TWEp11', 'since': '#TW0'}, {'interval': '0.7049', 'xml:id': 'TWSp12', 'since': '#TW0'}, {'interval': '0.9223', 'xml:id': 'TWEp12', 'since': '#TW0'}, {'interval': '0.9223', 'xml:id': 'TWSp13', 'since': '#TW0'}, {'interval': '1.6568', 'xml:id': 'TWEp13', 'since': '#TW0'}, {'interval': '1.6568', 'xml:id': 'TWSp14', 'since': '#TW0'}, {'interval': '1.7886', 'xml:id': 'TWEp14', 'since': '#TW0'}] 
>>> 
>>> for t1 , (t2,t3) in zip(w_list, zip(t_list[::2],t_list[1::2])): 
    print 'word: {0[0]:<10} start: {1[interval]:<10} end: {2[interval]:<10}'.format(t1, t2, t3) #for pretty printing 


word: right  start: 0   end: 0.2108  
word: _   start: 0.2108  end: 0.7049  
word: cough  start: 0.7049  end: 0.9223  
word: _   start: 0.9223  end: 1.6568  
word: go   start: 1.6568  end: 1.7886 
>>> 
>>> d = {} #save the needed data as a dictionary 
>>> for t1 , (t2,t3) in zip(w_list, zip(t_list[::2],t_list[1::2])): 
    d[t1[0]] = {'start':t2['interval'], 'end':t3['interval']} 
{'go': {'start': '1.6568', 'end': '1.7886'}, 'cough': {'start': '0.7049', 'end': '0.9223'}, 'right': {'start': '0', 'end': '0.2108'}, '_': {'start': '0.9223', 'end': '1.6568'}} 

EDIT:

Проблемы с предыдущим подходом является то, что если вы не уверены в том же сортировку как список, чтобы уйти от этого дела, сортировать оба списка в тот же заказ:

>>> import re 
>>> from operator import itemgetter 
>>> 
>>> t_sorted = sorted(t_list, key=lambda s:re.findall(r'\d+$',s['xml:id'])) 
>>> t_sorted = sorted(t_list, key=lambda s:s['xml:id'][-2:]) #if you are sure that the last two are always digits, but I don't recommend it for general cases 
>>> t_sorted 
[{'xml:id': 'TWSp10', 'interval': '0', 'since': '#TW0'}, {'xml:id': 'TWEp10', 'interval': '0.2108', 'since': '#TW0'}, {'xml:id': 'TWSp11', 'interval': '0.2108', 'since': '#TW0'}, {'xml:id': 'TWEp11', 'interval': '0.7049', 'since': '#TW0'}, {'xml:id': 'TWSp12', 'interval': '0.7049', 'since': '#TW0'}, {'xml:id': 'TWEp12', 'interval': '0.9223', 'since': '#TW0'}, {'xml:id': 'TWSp13', 'interval': '0.9223', 'since': '#TW0'}, {'xml:id': 'TWEp13', 'interval': '1.6568', 'since': '#TW0'}, {'xml:id': 'TWSp14', 'interval': '1.6568', 'since': '#TW0'}, {'xml:id': 'TWEp14', 'interval': '1.7886', 'since': '#TW0'}] 
>>> 
>>> w_sorted = sorted(w_list, key=itemgetter(1)) 
>>> w_sorted 
[['right', '#TWSp10', '#TWEp10'], ['_', '#TWSp11', '#TWEp11'], ['cough', '#TWSp12', '#TWEp12'], ['_', '#TWSp13', '#TWEp13'], ['go', '#TWSp14', '#TWEp14']] 
>>> d = {} #save the needed data as a dictionary 
>>> for t1 , (t2,t3) in zip(w_sorted, zip(t_sorted[::2],t_sorted[1::2])): 
    d[t1[0]] = {'start':t2['interval'], 'end':t3['interval']} 
+1

Это было бы лучше, чем мой ответ, если два списка всегда правильно упорядочены. – M4rtini

+0

@ M4rtini ... да .. Я собирался обновить свой ответ, чтобы отсортировать два списка в том же порядке, сначала –