2014-01-03 3 views
-1

Я пишу программу для тегов NER с nltk и Mallet. Мне нужно преобразовать два формата входных данных, которые я не могу изменить.Преобразование списка списков кортежей в кортеж списков списков в python

Данные в основном содержат слова со связанными с ними тегами для контролируемого обучения, но есть подразделение данных в предложениях, следовательно, список списков.

Первый формат

tuple(list(list(word)),list(list(tag))) 

, а второй формат

list(list(tuple(word,tag)) 

В настоящее время я преобразование его как этот (формат 2 => формат 1):

([[tup[0] for tup in sent] for sent in train_set], 
[[tup[1] for tup in sent] for sent in train_set]) 

Примеры данных:

[[('Steve','PERSON'),('runs','NONE'),('Apple','ORGANIZATION')],[('Today','NONE'),('is','NONE'),('June','DATETIME'),('27th','DATETIME')]] 

и ожидаемые результаты:

([['Steve', 'runs', 'Apple' ],['Today','is','June','27th']], 
    [['PERSON','NONE','ORGANIZATION'],['NONE','NONE','DATETIME','DATETIME']]) 

я выполнить преобразование в обоих направлениях

EDIT: Я не обязательно хочу, чтобы это было короче - пожалуйста, просто предложить лучший (и более читаемый) способ делая это в python 2.7 (с образцом кода).

+2

Предоставьте данные образца и ожидаемый результат. –

+2

Меньше символов ** не означает ** лучше. С вашим решением вы выполняете тот же цикл дважды. Если вы напишете его в классическом стиле «для ... в ...», это будет длиннее, но 1) более эффективным (один цикл) и 2) легче читать (ну, по крайней мере, для меня). – freakish

+0

объясните нижний предел, пожалуйста, – mz8i

ответ

2

Преобразование list(list(tuple(word,tag)) в tuple(list(list(word)),list(list(tag))) легко:

def convert(data_structure): 
    sentences, tags = data_structure 
    container = [] 
    for i in xrange(len(sentences)): 
     container.append(zip(sentences[i], tags[i])) 

    return container 

Код для преобразования в другую сторону, немного дольше, но не очень сложно, если вы просто использовать вложенные for петли:

def convert(data_structure): 
    sentences = [] 
    tags = [] 

    for sentence in data_structure: 
     sentence_words = [] 
     sentence_tags = [] 

     for word, tag in sentence: 
      sentence_words.append(word) 
      sentence_tags.append(tag) 

     sentences.append(sentence_words) 
     tags.append(sentence_tags) 

    return (sentences, tags) 

Возможно, код может быть сокращено больше, но общий принцип должен быть ясным, надеюсь.

+0

спасибо. код вполне читабельен. однако, я не понимаю часть с 'container' во втором фрагменте. не может ли это быть просто «return (предложения, теги)»? – mz8i

+0

Действительно, переменная 'container' здесь устарела. Я написал этот код очень быстро.Я рад, что мой ответ помог вам. :-) – pemistahl

1

Вы можете преобразовать внутренние кортежей итераторы (с использованием iter), а затем вызвать next на них во вложенном списке понимание:

lis = [[('Steve','PERSON'),('runs','NONE'),('Apple','ORGANIZATION')], 
     [('Today','NONE'),('is','NONE'),('June','DATETIME'),('27th','DATETIME')]] 

it = [[iter(y) for y in x] for x in lis] 
n = len(lis[0][0]) #Number of iterations required. 
print [[[next(x) for x in i] for i in it] for _ in range(n)] 

Выход:

[[['Steve', 'runs', 'Apple'], ['Today', 'is', 'June', '27th']], 
[['PERSON', 'NONE', 'ORGANIZATION'], ['NONE', 'NONE', 'DATETIME', 'DATETIME']]] 
0

Я думаю, что правильный решение будет следующим:

>>> data = [[('Steve','PERSON'),('runs','NONE'),('Apple','ORGANIZATION')],[('Today','NONE'),('is','NONE'),('June','DATETIME'),('27th','DATETIME')]] 
>>> tuple([ map(list, (zip(*x))) for x in data ]) 
([['Steve', 'runs', 'Apple'], ['PERSON', 'NONE', 'ORGANIZATION']], [['Today', 'is', 'June', '27th'], ['NONE', 'NONE', 'DATETIME', 'DATETIME']]) 
+0

, к сожалению, это не дает ожидаемого результата. пожалуйста, перепроверьте мой вопрос – mz8i

+0

Да, правда. позвольте мне снова проверить. – iamsudip

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