I have this text file:
English
hello bye
italian
ciao hola
spanish
hola chao
I want to create a dictionary from each 2 consecutive lines:
{
'English': 'hello bye',
'italian': 'ciao hola',
'spanish': 'hola chao',
}
Here's my code:
d= {}
with open("test.txt", 'r') as f:
l = f.readlines()
for line in l:
(key,val) = line.split()
d[key]=val
I get the error:
too many values to unpack error
You can also use this approach:
d = {}
with open("test.txt", 'r') as f:
l = f.readlines()
i = 0
while i < len(l):
d[l[i].replace("\n","")] = l[i+1].replace("\n","")
i += 2
In your original code, you are reading all lines in the file in one go using f.readlines() and then you are splitting each line. The problem is that not each line is giving you a list with two elements, so key, val = line.split() gives you a values to unpack, since you are trying to assign a single element list to two items. e.g a,b = [2] which will result in this error like so.
In [66]: a,b = [2]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-66-f9f79b7d1d3c> in <module>
----> 1 a,b = [2]
ValueError: not enough values to unpack (expected 2, got 1)
To avoid it, we just iterate through the lines we read, and every even element is a key and every odd element is a value in the dictionary.
dct = {}
with open("file.txt", 'r') as f:
l = f.readlines()
idx = 0
while idx < len(l):
#Even element is key, Odd element is value
key = l[idx].strip()
value = l[idx+1].strip()
dct[key] = value
idx+=2
#{'English': 'hello bye', 'italian': 'ciao hola', 'spanish': 'hola chao'}
Or a more terse solution using dict-comprehension is
l = []
with open("file.txt", 'r') as f:
l = f.readlines()
#This will be a list of tuples, with the first element of tuple being the key #and second value being the value
#Keys are obtained by slicing all even indexes, and values by slicing all odd indexes
key_value_tups = zip(l[::2], l[1::2])
#[('English \n', 'hello bye \n'), ('italian \n', 'ciao hola\n'), ('spanish\n', 'hola chao\n')]
#Iterate through the tuples and create the dict via dict-comprehension
dct = {key.strip() : value.strip() for key, value in key_value_tups}
print(dct)
#{'English': 'hello bye', 'italian': 'ciao hola', 'spanish': 'hola chao'}
i = 0
d = {}
prev_key = None
for line in l:
if i % 2 == 0:
prev_key = line
else:
d[prev_key] = line
i += 1
You can do it in a single line :
with open("test.txt", 'r') as f:
lines = f.readlines()
dict( zip( lines[::2], lines[1::2] ) )
lines[::2] will give you all the elements of lines that have an even index
lines[1::2] will give you all the elements of lines that have an odd index
zip will create an iterator (list1 elem, list2 elem) from the two lists
dict will take each tuple (key, value) from the iterator as a dictionary item and create a dictionary
That one line is the equivalent of :
keys = []
values = []
for index, elem in enumerate(lines):
if index % 2 == 0:
keys += [elem]
else:
values += [elem]
d = {}
for key, val in zip(keys, values):
d[key] = val
Use a dictionary-comprehension using zip():
with open("test.txt", 'r') as f:
l = f.readlines()
d = {x: y for x, y in zip(l[::2], l[1::2])}
Related
i would like to know how I could create a dictionary using the three lists. coun_keys to be a key and months_values and cases_values are to be the values.
I only found sources where I could use the zip() function to have a key: value, but how can I have key: value1, value2?
def main(csvfile,country ,type ):
with open(csvfile,"r") as file:
if type.lower() == "statistics ":
coun_keys = []
months_values = []
cases_values = []
listname =[]
coun_month={}
for line in file:
columns = (line.strip().split(","))
listname.append(columns)
listname.pop(0)
for line in listname:
date1 = line[3].split("/")
coun_keys.append(str(line[2]))
months_values.append(int(date1[1]))
cases_values.append(int(line[4]))
Do you mean, like:
list1 = [1, 2, 3]
list2 = 'abc'
list3 = [5, 6, 7]
print(dict(zip(list1,zip(list2, list3))))
#############################
For your code specifically, I would break up what you want to do into pieces. First define what you want to do with each line of your file:
def process_line(line):
line = line.strip().split(',')
date1 = line[3].split("/")
key = str(line[2])
month = int(date1[1])
case = int(line[4])
return key,(month,case)
Notice I group the values I want in a tuple, in particular, I want the process_line function to return my "key" and my "value" (a pair). Now open your file and process the lines:
f = open(csvfile)
next(f) #Skip the first line
result = dict(process_line(line) for line in f)
f.close()
This might help...
newDict = dict(zip(coun_keys, [months_values, cases_values]))
Assuming they're the same length, you can also do:
your_dict = {coun_keys[i] : (months_values[i], cases_values[i]) for i in range(len(coun_keys))}
For example,
lst1 = [a,b,c,d]
lst2 = [1,2,3,4]
lst3 = [5,6,7,8]
dict1 = dict(zip(lst1,zip(lst2,lst3)))
I want to match a certain string in a CSV file and return the column of the string within the CSV file for example
import csv
data = ['a','b','c'],['d','e','f'],['h','i','j']
for example I'm looking for the word e, I want it to return [1] as it is in the second column.
The solution using csv.reader object and enumerate function(to get key/value sequence):
def get_column(file, word):
with open(file) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
for k,v in enumerate(row):
if v == word:
return k # immediate value return to avoid further loop iteration
search_word = 'e'
print(get_column("data/sample.csv", search_word)) # "data/sample.csv" is an exemplary file path
The output:
1
I am not sure why do you need csv in this example.
>>> data = ['a','b','c'],['d','e','f'],['h','i','j']
>>>
>>>
>>> string = 'e'
>>> for idx, lst in enumerate(data):
... if string in lst:
... print idx
1
A variation of wolendranh's answer:
>>> data = ['a','b','c'],['d','e','f'],['h','i','j']
>>> word = 'e'
>>> for row in data:
... try:
... print(row.index(word))
... except ValueError:
... continue
Try the following:
>>> data_list = [['a','b','c'],['d','e','f'],['h','i','j']]
>>> col2_list = []
>>>
>>> for d in data_list:
... col2=d[1]
... col2_list.append(col2)
So in the end you get a list with all the values of column [1]:
col2_list = ["b","e","i"]
Say I have a file "stuff.txt" that contains the following on separate lines:
q:5
r:2
s:7
I want to read each of these lines from the file, and convert them to dictionary elements, the letters being the keys and the numbers the values.
So I would like to get
y ={"q":5, "r":2, "s":7}
I've tried the following, but it just prints an empty dictionary "{}"
y = {}
infile = open("stuff.txt", "r")
z = infile.read()
for line in z:
key, value = line.strip().split(':')
y[key].append(value)
print(y)
infile.close()
try this:
d = {}
with open('text.txt') as f:
for line in f:
key, value = line.strip().split(':')
d[key] = int(value)
You are appending to d[key] as if it was a list. What you want is to just straight-up assign it like the above.
Also, using with to open the file is good practice, as it auto closes the file after the code in the 'with block' is executed.
There are some possible improvements to be made. The first is using context manager for file handling - that is with open(...) - in case of exception, this will handle all the needed tasks for you.
Second, you have a small mistake in your dictionary assignment: the values are assigned using = operator, such as dict[key] = value.
y = {}
with open("stuff.txt", "r") as infile:
for line in infile:
key, value = line.strip().split(':')
y[key] = (value)
print(y)
Python3:
with open('input.txt', 'r', encoding = "utf-8") as f:
for line in f.readlines():
s=[] #converting strings to list
for i in line.split(" "):
s.append(i)
d=dict(x.strip().split(":") for x in s) #dictionary comprehension: converting list to dictionary
e={a: int(x) for a, x in d.items()} #dictionary comprehension: converting the dictionary values from string format to integer format
print(e)
I have a text file with tuples in it that I would like to convert to a list with indices as follows:
2, 60;
3, 67;
4, 67;
5, 60;
6, 60;
7, 67;
8, 67;
Needs to become:
60, 2 5 6
67, 3 4 7 8
And so on with many numbers...
I've made it as far as reading in the file and getting rid of the punctuation and casting it as ints, but I'm not quite sure how to iterate through and add multiple items at a given index of a list. Any help would be much appreciated!
Here is my code so far:
with open('cues.txt') as f:
lines = f.readlines()
arr = []
for i in lines:
i = i.replace(', ', ' ')
i = i.replace(';', '')
i = i.replace('\n', '')
arr.append(i)
array = []
for line in arr: # read rest of lines
array.append([int(x) for x in line.split()])
arr = []
#make array of first values 40 to 80
for i in range(40, 81):
arr.append(i)
print arr
for j in range(0, len(array)):
for i in array:
if (i[0] == arr[j]):
arr[i[0]].extend(i[1])
Do you need it in a list you can simply collect them into a dict:
i = {}
with open('cues.txt') as f:
for (x, y) in (l.strip(';').split(', ') for l in f):
i.setdefault(y, []).append(x)
for k, v in i.iteritems():
print "{0}, {1}".format(k, " ".join(v))
You could use defaultdict function from collections module.
from collections import defaultdict
with open('file') as f:
l = []
for line in f:
l.append(tuple(line.replace(';','').strip().split(', ')))
m = defaultdict(list)
for i in l:
m[i[1]].append(i[0])
for j in m:
print j+", "+' '.join(m[j])
You can use a dict to store the index:
results = {}
with open("cues.txt") as f:
for line in f:
value, index = line.strip()[:-1].split(", ")
if index not in results:
results[index] = [value]
else:
results[index].append(value)
for index in results:
print("{0}, {1}".format(index, " ".join(results[index]))
1) This code is wrong at many level. See inline comment
arr = []
for i in lines:
i = i.replace(', ', ' ')
i = i.replace(';', '')
i = i.replace('\n', '') # Wrong identation. You will only get the last line in arr
arr.append(i)
You can simply do
arr = []
for i in lines:
i = i.strip().replace(';', '').split(", ")
arr.append(i)
It will remove newline character, remove ; and nicely split a line into a tuple of (index, value)
2) This code can be simplified to one line
arr = [] # It should not be named `arr` because it destroyed the arr created in stage 1
for i in range(40, 81):
arr.append(i)
print arr
becomes:
result = range(40, 81)
But it is not an ideal data structure for your problem. You should use dictionary instead. In the other word, you can lose this bit of code altogether
3) Finally you are ready to iterate arr and build the result
result = defaultdict(list)
for a in arr:
result[a[1]].append(a[0])
You should use dict to save text data, the following code:
d = {}
with open('cues.txt') as f:
lines = f.readlines()
for line in lines:
line = line.split(',')
key = line[1].strip()[0:-1]
if d.has_key(key):
d[key].append(line[0])
else:
d[key] = [line[0]]
for key, value in d.iteritems():
print "{0}, {1}".format(key, " ".join(value))
I have a file comprising two columns, i.e.,
1 a
2 b
3 c
I wish to read this file to a dictionary such that column 1 is the key and column 2 is the value, i.e.,
d = {1:'a', 2:'b', 3:'c'}
The file is small, so efficiency is not an issue.
d = {}
with open("file.txt") as f:
for line in f:
(key, val) = line.split()
d[int(key)] = val
This will leave the key as a string:
with open('infile.txt') as f:
d = dict(x.rstrip().split(None, 1) for x in f)
You can also use a dict comprehension like:
with open("infile.txt") as f:
d = {int(k): v for line in f for (k, v) in [line.strip().split(None, 1)]}
def get_pair(line):
key, sep, value = line.strip().partition(" ")
return int(key), value
with open("file.txt") as fd:
d = dict(get_pair(line) for line in fd)
By dictionary comprehension
d = { line.split()[0] : line.split()[1] for line in open("file.txt") }
Or By pandas
import pandas as pd
d = pd.read_csv("file.txt", delimiter=" ", header = None).to_dict()[0]
Simple Option
Most methods for storing a dictionary use JSON, Pickle, or line reading. Providing you're not editing the dictionary outside of Python, this simple method should suffice for even complex dictionaries. Although Pickle will be better for larger dictionaries.
x = {1:'a', 2:'b', 3:'c'}
f = 'file.txt'
print(x, file=open(f,'w')) # file.txt >>> {1:'a', 2:'b', 3:'c'}
y = eval(open(f,'r').read())
print(x==y) # >>> True
If you love one liners, try:
d=eval('{'+re.sub('\'[\s]*?\'','\':\'',re.sub(r'([^'+input('SEP: ')+',]+)','\''+r'\1'+'\'',open(input('FILE: ')).read().rstrip('\n').replace('\n',',')))+'}')
Input FILE = Path to file, SEP = Key-Value separator character
Not the most elegant or efficient way of doing it, but quite interesting nonetheless :)
IMHO a bit more pythonic to use generators (probably you need 2.7+ for this):
with open('infile.txt') as fd:
pairs = (line.split(None) for line in fd)
res = {int(pair[0]):pair[1] for pair in pairs if len(pair) == 2 and pair[0].isdigit()}
This will also filter out lines not starting with an integer or not containing exactly two items
I had a requirement to take values from text file and use as key value pair. i have content in text file as key = value, so i have used split method with separator as "=" and
wrote below code
d = {}
file = open("filename.txt")
for x in file:
f = x.split("=")
d.update({f[0].strip(): f[1].strip()})
By using strip method any spaces before or after the "=" separator are removed and you will have the expected data in dictionary format
import re
my_file = open('file.txt','r')
d = {}
for i in my_file:
g = re.search(r'(\d+)\s+(.*)', i) # glob line containing an int and a string
d[int(g.group(1))] = g.group(2)
Here's another option...
events = {}
for line in csv.reader(open(os.path.join(path, 'events.txt'), "rb")):
if line[0][0] == "#":
continue
events[line[0]] = line[1] if len(line) == 2 else line[1:]