2016-01-07 2 views
1

У меня есть файл, в котором мои данные, как:Read & разделить файл в словарь

1 [0,1, 4, 89]  
2 [3, 56, 6]  
3 [3,4,0] 

И так далее.

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

dictionary = {} 

with open('file.txt') as f: 
    for line in f: 
     nb, list = line.split(' ') 
     dictionary[nb] = list 

Тогда я буду делать что-то вроде:

for e in dictionary: 
    etc. 

у меня есть эта ошибка:

too many values to unpack 

, потому что я не знаю, как бороться с SECO nd split, который является списком.

Есть ли другой способ доступа и работы с любым входным файлом легко?

+0

взгляд на это, что вы получаете от spliting строку '[ '1', '[0,1,', '4', '89]]' – Netwave

ответ

3

Прежде всего, вы можете установить аргумент maxsplitstr.split(). Из документа:

str.split(sep=None, maxsplit=-1)

Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1 , then there is no limit on the number of splits (all possible splits are made).

Демо:

>>> s = '1 [0,1, 4, 89]' 
>>> s.split(' ', 1) 
['1', '[0,1, 4, 89]'] 
>>> s.split(' ') 
['1', '[0,1,', '4,', '89]'] 

>>> s.split(' ')[1] 
'[0,1,' 
>>> s.split(' ', 1)[1] 
'[0,1, 4, 89]' 

Затем вам нужно преобразовать строку списка в реальный список. Я бы рекомендовал использовать ast.literal_eval(). Из документа:

ast.literal_eval(node_or_string)

Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None .

Например:

>>> import ast 
>>> s = '1 [0,1, 4, 89]' 
>>> s.split(' ', 1)[1] 
'[0,1, 4, 89]' 
>>> ast.literal_eval(s.split(' ', 1)[1]) 
[0, 1, 4, 89] 
>>> type(ast.literal_eval(s.split(' ', 1)[1])) 
<class 'list'> 
>>> type(s.split(' ', 1)[1]) 
<class 'str'> 

Если вам нужно удалить \n после строки, просто используйте str.strip().Из документа:

str.strip([chars])

Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace.

использовать его как это:

>>> ' 1 [0,1, 4, 89] '.strip() 
'1 [0,1, 4, 89]' 
>>> '1 [0,1, 4, 89]\n'.strip() 
'1 [0,1, 4, 89]' 
>>> 

Она удаляет все вкладки, переводы строк, пробелы до и после строки, если вы просто хотите удалить пробелы, новые строки до или после того, как строку, посмотрите на str.lstrip() и str.rstrip().


Таким образом, вы можете написать код так:

import ast 
dictionary = {} 

with open('file.txt') as f: 
    for line in f: 
     key, value = line.strip().split(1) 
     dictionary[key] = value 

Если вы хотите клавиши со dictionary «s быть ИНТ объекты, просто использовать int() функцию, чтобы преобразовать его нравится:

import ast 
dictionary = {} 

with open('file.txt') as f: 
    for line in f: 
     key, value = line.strip().split(' ', 1) 
     dictionary[int(key)] = value 
+0

Спасибо! Он работает :), если возможно, как избежать/n в конце списка? Я не могу указать, что значения являются целыми (например, мы можем сделать это легко для ключей при построении словаря). –

+0

@ H.eyXD: Хорошо, если ответ полезен, помните, что он отмечен как принятый ответ. Пожалуйста, ознакомьтесь с нашими [tour] и [help] для получения более подробной информации. –

+0

@ H.eyXD: Хорошо, я отредактировал свой ответ. –

1

Будет ли это делать?

import ast 
d = dict() 
with open('file.txt') as f: 
    for line in f: 
     k, l = line.split(' ', 1) 
     d[k] = ast.literal_eval(l) 

print(d) 

производит

{'3': [3, 4, 0], '1': [0, 1, 4, 89], '2': [3, 56, 6]} 

В случае, если вы хотите ключ, чтобы быть целым числом, а не строка просто сделать

d[int(k)] = ast.literal_eval(l) 
+0

Я не могу этого сделать, потому что split() не принимает никаких аргументов (может быть, потому, что я работаю с python 2.7)? –

+1

@ H.eyXD - Я настроил теги этого вопроса, чтобы учесть эту информацию. Вам нужно будет использовать один из ответов с '('', 1)'. Pynchia, я бы порекомендовал 'ast.literal_eval()' over 'eval()' для такого рода вещей. – TigerhawkT3

+1

@ TigerhawkT3 эй, мой был с '('', 1)' ... Я изменил его, потому что было лучше скрыть имя параметра, как вы это сделали ... Я его поменяю ... BTW, это wodl будет здорово знать версию python заранее – Pynchia

1

Используйте maxsplit аргумент и ast.literal_eval():

import ast 
dictionary = {} 

with open('file.txt') as f: 
    for line in f: 
     nb, l = line.split(maxsplit=1) 
     dictionary[nb] = ast.literal_eval(l) 

Обратите внимание, что я изменил имя list на то, что не маскирует встроенную функцию list() и использует разделитель по умолчанию для любых пробелов.

1

Для сохранения данных Использование eval ast.literal_eval:

from ast import literal_eval 

data = {} 
with open('file.txt') as fobj: 
    for line in fobj: 
     key, rest = line.split(None, 1) 
     data[key] = literal_eval(rest) 


>>> data 
{'1': [0, 1, 4, 89], '2': [3, 56, 6], '3': [3, 4, 0]} 

Из документов:

ast.literal_eval(node_or_string) 

This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself.

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