2016-01-25 2 views
1

У меня есть входной файл, содержащий строки:Запись цикла питон два уровня понимания

key \t value1 \t value2 ..... 

Я хотел бы прочитать этот файл в словарь, где ключ является первым знаком строки и значение список значений.

Я думаю, что-то вроде этого будет делать это, но python дает мне ошибку, что имя l не определено. Как написать понимание, которое имеет два уровня «для» таких утверждений?

f = open("input.txt") 
datamap = {tokens[0]:tokens[1:] for tokens in l.split("\t") for l in enumerate(f)} 
+0

Я предложил бы использовать модуль для чтения CSV, чтобы сделать эту работу вместо того, разделив его вручную самостоятельно. https://docs.python.org/3/library/csv.html. Также посмотрите на функцию dictreader https://docs.python.org/3/library/csv.html#csv.DictReader – canyon289

+0

Используйте тот же порядок, что и для вложенных циклов: '{... для l в перечислении (f) для токенов в l.split ("\ t")} '. Выражение можно представить как тело самого внутреннего цикла. – chepner

ответ

6

Используйте csv модуль и вставить каждую строку в словарь:

import csv 

with open('input.txt') as tsvfile: 
    reader = csv.reader(tsvfile, delimiter='\t') 
    datamap = {row[0]: row[1:] for row in reader} 

Это обходит проблему в целом.

Вы может поставить str.split() результат в кортеж, чтобы создать «переменную цикл»:

datamap = {row[0]: row[1:] for l in f for row in (l.strip().split("\t"),)} 

Здесь row привязываются к одному str.split() результату из кортежа, фактически создавая row = l.strip().split('\t') «назначения» ,

2

Martijn's получили вы охвачены для улучшения процесса, но только на непосредственное решение вопросов, которые вы видели с кодом:

Во-первых, enumerate не делать то, что вы думаете, что он делает (хотя я не совсем уверен, что вы думаете, что это делает). Вы можете просто избавиться от него.

Во-вторых, Python пытается решить эту проблему:

tokens[0]:tokens[1:] for tokens in l.split("\t") 

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

datamap = {tokens[0]:tokens[1:] for tokens in (l.split("\t") for l in f)} 
+0

Спасибо! Мне это было любопытно. :) – pandagrammer