How can I store this in a dictionary? - python

I must write a dictionary. This is my first time doing it and I can't wrap my head around it. The first 5 element should be the key to it and the rest the value.
for i in verseny:
if i not in eredmeny:
eredmeny[i] = 1
else:
eredmeny[i] += 1
YS869 CCCADCADBCBCCB this is a line from the hw. This YS869 should be the key and this CCCADCADBCBCCB should be the value.
The problem is that I can't store them in a dictionary. I'm grinding gears here but getting nowhere.

Assuming that erdemeny is your dictionary name and that verseny is the list that includes your values and keys strings. This should do it:
verseny = ['YS869 CCCADCADBCBCCB', 'CS769 CCCADCADBCBCCB', 'BS869 CCCADCADBCBCCB']
eredmeny = {}
for i in verseny:
key, value = i.split(' ')[0], i.split(' ')[1]
if key not in eredmeny.keys():
eredmeny[key] = value
else:
eredmeny[key].append(value)

I'm not really understanding the question well, but an easy way to do the task at hand would be converting the list into a string and then using split():
line = 'YS869 CCCADCADBCBCCB'
words = l.split()
d = {ls[0]: ls[1]}
print(d)

this is the basic skill in python. I hope you can refer to the existing materials. As your example, the following demonstrations are given:
line = 'YS869 CCCADCADBCBCCB'
dictionary = {}
dictionary[line[:4]] = line[5:]
print(dictionary) # {'YS86': ' CCCADCADBCBCCB'}

Related

Editing dictionary key names based on a specific value

After converting to a string represented dictionary in Python I am looking to edit some key names based on a particular value. Here's an example of the dictionary in string format:
s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", ' \
'"device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", ' \
'"device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", ' \
'"additional.info":"Hi Again",}'
I have a working method below, which converts the string into a dictionary, scans for key entries containing '.Type' and drops into a list a tuple of the key section to replace and what to replace it with. However the whole process seems too inefficient, is there a better way to do this?
I have key value pairs of interest in my dictionary like this:
'device.0.Type':'DEVICE-X'
'device.1.Type':'DEVICE-Y'
'device.2.Type':'DEVICE-Z'
What I am looking to do is change all Key name instances of device.X to the value given for key 'device.X.Type'.
For example:
'device.0.Id':'12345678', 'device.0.Type':'DEVICE-X', 'device.0.Status':'ACTIVE',
'device.1.Id':'123EFEF8', 'device.1.Type':'DEVICE-Y', 'device.1.Status':'NOT FOUND', etc
would become:
'DEVICE-X.Id':'12345678', 'DEVICE-X.Type':'DEVICE-X', 'DEVICE-X.Status':'ACTIVE',
'DEVICE-Y.Id':'123EFEF8', 'DEVICE-Y.Type':'DEVICE-Y', 'DEVICE-Y.Status':'NOT FOUND', etc
Basically I am looking to remove the ambiguity of 'device.X' with something that's easier to read based on the device type
Here's my longwinded version:
s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", ' \
'"device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", ' \
'"device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", ' \
'"additional.info":"Hi Again",}'
d = eval(s)
devs = []
for k, v in d.items():
if '.Type' in k:
devs.append((k.split('.Type')[0], v))
for item in devs:
if item[0] in s:
s = s.replace(item[0], item[1])
s = eval(s)
print(s)
You can solve this by loading the data as a json, then iterating over it:
import json
s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", "device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", "device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", "additional.info":"Hi Again"}'
# load the string to a dictionary
devices_data = json.loads(s)
device_names = {}
for key, value in devices_data.items():
if key.endswith("Type"):
# if the key looks like a device type, store the value
device_names[key.rpartition(".")[0]] = value
renamed_device_data = {}
for key, value in devices_data.items():
x = key.rpartition(".") # split the key apart
if x[0] in device_names: # check if the first part matches a device name
renamed_device_data[f"{device_names[x[0]]}.{x[2]}"] = value # add the new key to the renamed dictionary with the value
else:
renamed_device_data[key] = value # for non-matches, put them in as is
This could certainly be optimised, but it should work at least!

How to sort a Python dictionary by a substring contained in the keys, according to the order set in a list?

I'm very new to Python and I'm stuck on a task. First I made a file containing a number of fasta files with sequence names into a dictionary, then managed to select only those I want, based on substrings included in the keys which are defined in list "flu_genes".
Now I'm trying to reorder the items in this dictionary based on the order of substrings defined in the list "flu_genes". I'm completely stuck; I found a way of reordering based on the key order in a list BUT it is not my case, as the order is defined not by the keys but by a substring within the keys.
Should also add that in this case the substring its at the end with format "_GENE", however it could be in the middle of the string with the same format, perhaps "GENE", therefore I'd rather not rely on a code to find the substring at the end of the string.
I hope this is clear enough and thanks in advance for any help!
"full_genome.fasta"
>A/influenza/1/1_NA
atgcg
>A/influenza/1/1_NP
ctgat
>A/influenza/1/1_FluB
agcta
>A/influenza/1/1_HA
tgcat
>A/influenza/1/1_FluC
agagt
>A/influenza/1/1_M
tatag
consensus = {}
flu_genes = ['_HA', '_NP', '_NA', '_M']
with open("full_genome.fasta", 'r') as myseq:
for line in myseq:
line = line.rstrip()
if line.startswith('>'):
key = line[1:]
else:
if key in consensus:
consensus[key] += line
else:
consensus[key] = line
flu_fas = {key : val for key, val in consensus.items() if any(ele in key for ele in flu_genes)}
print("Dictionary after removal of keys : " + str(flu_fas))
>>>Dictionary after removal of keys : {'>A/influenza/1/1_NA': 'atgcg', '>A/influenza/1/1_NP': 'ctgat', '>A/influenza/1/1_HA': 'tgcat', '>A/influenza/1/1_M': 'tatag'}
#reordering by keys order (not going to work!) as in: https://try2explore.com/questions/12586065
reordered_dict = {k: flu_fas[k] for k in flu_genes}
A dictionary is fundamentally unsorted, but as an implementation detail of python3 it remembers its insertion order, and you're not going to change anything later, so you can do what you're doing.
The problem is, of course, that you're not working with the actual keys. So let's just set up a list of the keys, and sort that according to your criteria. Then you can do the other thing you did, except using the actual keys.
flu_genes = ['_HA', '_NP', '_NA', '_M']
def get_gene_index(k):
for index, gene in enumerate(flu_genes):
if k.endswith(gene):
return index
raise ValueError('I thought you removed those already')
reordered_keys = sorted(flu_fas.keys(), key=get_gene_index)
reordered_dict = {k: flu_fas[k] for k in reordered_keys}
for k, v in reordered_dict.items():
print(k, v)
A/influenza/1/1_HA tgcat
A/influenza/1/1_NP ctgat
A/influenza/1/1_NA atgcg
A/influenza/1/1_M tatag
Normally, I wouldn't do an n-squared sort, but I'm assuming the lines in the data file is much larger than the number of flu_genes, making that essentially a fixed constant.
This may or may not be the best data structure for your application, but I'll leave that to code review.
It's because you are trying to reorder it with non-existent dictionary keys. Your keys are
['>A/influenza/1/1_NA', '>A/influenza/1/1_NP', '>A/influenza/1/1_HA', '>A/influenza/1/1_M']
which doesn't match the list
['_HA', '_NP', '_NA', '_M']
you first need to get transform them to make them match and since we know the pattern that it's at the end of the string starting with an underscore, we can split at underscores and get the last match.
consensus = {}
flu_genes = ['_HA', '_NP', '_NA', '_M']
with open("full_genome.fasta", 'r') as myseq:
for line in myseq:
line = line.rstrip()
if line.startswith('>'):
sequence = line
gene = line.split('_')[-1]
key = f"_{gene}"
else:
consensus[key] = {
'sequence': sequence,
'data': line
}
flu_fas = {key : val for key, val in consensus.items() if any(ele in key for ele in flu_genes)}
print("Dictionary after removal of keys : " + str(flu_fas))
reordered_dict = {k: flu_fas[k] for k in flu_genes}

Python: dictionary to collection

I have a file with 2 columns:
Anzegem Anzegem
Gijzelbrechtegem Anzegem
Ingooigem Anzegem
Aalst Sint-Truiden
Aalter Aalter
The first column is a town and the second column is the district of that town.
I made a dictionary of that file like this:
def readTowns(text):
input = open(text, 'r')
file = input.readlines()
dict = {}
verzameling = set()
for line in file:
tmp = line.split()
dict[tmp[0]] = tmp[1]
return dict
If I set a variable 'writeTowns' equal to readTowns(text) and do writeTown['Anzegem'], I want to get a collection of {'Anzegem', 'Gijzelbrechtegem', 'Ingooigem'}.
Does anybody know how to do this?
I think you can just create another function that can create appropriate data structure for what you need. Because, at the end you will end up writing code which basically manipulates the dictionary returned by readTowns to generate data as per your requirement. Why not keep the code clean and create another function for that. You Just create a name to list dictionary and you are all set.
def writeTowns(text):
input = open(text, 'r')
file = input.readlines()
dict = {}
for line in file:
tmp = line.split()
dict[tmp[1]] = dict.get(tmp[1]) or []
dict.get(tmp[1]).append(tmp[0])
return dict
writeTown = writeTowns('file.txt')
print writeTown['Anzegem']
And if you are concerned about reading the same file twice, you can do something like this as well,
def readTowns(text):
input = open(text, 'r')
file = input.readlines()
dict2town = {}
town2dict = {}
for line in file:
tmp = line.split()
dict2town[tmp[0]] = tmp[1]
town2dict[tmp[1]] = town2dict.get(tmp[1]) or []
town2dict.get(tmp[1]).append(tmp[0])
return dict2town, town2dict
dict2town, town2dict = readTowns('file.txt')
print town2dict['Anzegem']
You could do something like this, although, please have a look at #ubadub's answer, there are better ways to organise your data.
[town for town, region in dic.items() if region == 'Anzegem']
It sounds like you want to make a dictionary where the keys are the districts and the values are a list of towns.
A basic way to do this is:
def readTowns(text):
with open(text, 'r') as f:
file = input.readlines()
my_dict = {}
for line in file:
tmp = line.split()
if tmp[1] in dict:
my_dict[tmp[1]].append(tmp[0])
else:
my_dict[tmp[1]] = [tmp[0]]
return dict
The if/else blocks can also be achieved using python's defaultdict subclass (docs here) but I've used the if/else statements here for readability.
Also some other points: the variables dict and file are python types so it is bad practice to overwrite these with your own local variable (notice I've changed dict to my_dict in the code above.
If you build your dictionary as {town: district}, so the town is the key and the district is the value, you can't do this easily*, because a dictionary is not meant to be used in that way. Dictionaries allow you to easily find the values associated with a given key. So if you want to find all the towns in a district, you are better of building your dictionary as:
{district: [list_of_towns]}
So for example the district Anzegem would appear as {'Anzegem': ['Anzegem', 'Gijzelbrechtegem', 'Ingooigem']}
And of course the value is your collection.
*you could probably do it by iterating through the entire dict and checking where your matches occur, but this isn't very efficient.

how to use string as list's indices in Python

for line in f.readlines():
(addr, vlanid, videoid, reqs, area) = line.split()
if vlanid not in dict:
dict[vlanid] = []
video_dict = dict[vlanid]
if videoid not in video_dict:
video_dict[videoid] = []
video_dict[videoid].append((addr, vlanid, videoid, reqs, area))
Here is my code, I want to use videoid as indices to creat a list. the real data of videoid are different strings like this : FYFSYJDHSJ
I got this error message:
video_dict[videoid] = []
TypeError: list indices must be integers, not str
But now how to add identifier like 1,2,3,4 for different strings in this case?
Use a dictionary instead of a list:
if vlanid not in dict:
dict[vlanid] = {}
P.S. I recommend that you call dict something else so that it doesn't shadow the built-in dict.
Don't use dict as a variable name. Try this (d instead of dict):
d = {}
for line in f.readlines():
(addr, vlanid, videoid, reqs, area) = line.split()
video_dict = d.setdefault(vlanid, {})
video_dict.setdefault(videoid, []).append((addr, vlanid, videoid, reqs, area))
As suggested above, creating dictionaries would be the most ideal code to implement. (Although you should avoid calling them dict, as that means something important to Python.
Your code may look something like what #aix had already posted above:
for line in f.readlines():
d = dict(zip(("addr", "vlanid", "videoid", "reqs", "area"), tuple(line.split())))
You would be able to do something with the dictionary d later in your code. Just remember - iterating through this dictionary will mean that, if you don't use d until after the loop is complete, you'll only get the last values from the file.

Python: create dict from list and auto-gen/increment the keys (list is the actual key values)?

i've searched pretty hard and cant find a question that exactly pertains to what i want to..
I have a file called "words" that has about 1000 lines of random A-Z sorted words...
10th
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
a
AAA
AAAS
Aarhus
Aaron
AAU
ABA
Ababa
aback
abacus
abalone
abandon
abase
abash
abate
abater
abbas
abbe
abbey
abbot
Abbott
abbreviate
abc
abdicate
abdomen
abdominal
abduct
Abe
abed
Abel
Abelian
I am trying to load this file into a dictionary, where using the word are the key values and the keys are actually auto-gen/auto-incremented for each word
e.g {0:10th, 1:1st, 2:2nd} ...etc..etc...
below is the code i've hobbled together so far, it seems to sort of works but its only showing me the last entry in the file as the only dict pair element
f3data = open('words')
mydict = {}
for line in f3data:
print line.strip()
cmyline = line.split()
key = +1
mydict [key] = cmyline
print mydict
key = +1
+1 is the same thing as 1. I assume you meant key += 1. I also can't see a reason why you'd split each line when there's only one item per line.
However, there's really no reason to do the looping yourself.
with open('words') as f3data:
mydict = dict(enumerate(line.strip() for line in f3data))
dict(enumerate(x.rstrip() for x in f3data))
But your error is key += 1.
f3data = open('words')
print f3data.readlines()
The use of zero-based numeric keys in a dict is very suspicious. Consider whether a simple list would suffice.
Here is an example using a list comprehension:
>>> mylist = [word.strip() for word in open('/usr/share/dict/words')]
>>> mylist[1]
'A'
>>> mylist[10]
"Aaron's"
>>> mylist[100]
"Addie's"
>>> mylist[1000]
"Armand's"
>>> mylist[10000]
"Loyd's"
I use str.strip() to remove whitespace and newlines, which are present in /usr/share/dict/words. This may not be necessary with your data.
However, if you really need a dictionary, Python's enumerate() built-in function is your friend here, and you can pass the output directly into the dict() function to create it:
>>> mydict = dict(enumerate(word.strip() for word in open('/usr/share/dict/words')))
>>> mydict[1]
'A'
>>> mydict[10]
"Aaron's"
>>> mydict[100]
"Addie's"
>>> mydict[1000]
"Armand's"
>>> mydict[10000]
"Loyd's"
With keys that dense, you don't want a dict, you want a list.
with open('words') as fp:
data = map(str.strip, fp.readlines())
But if you really can't live without a dict:
with open('words') as fp:
data = dict(enumerate(X.strip() for X in fp))
{index: x.strip() for index, x in enumerate(open('filename.txt'))}
This code uses a dictionary comprehension and the enumerate built-in, which takes an input sequence (in this case, the file object, which yields each line when iterated through) and returns an index along with the item. Then, a dictionary is built up with the index and text.
One question: why not just use a list if all of your keys are integers?
Finally, your original code should be
f3data = open('words')
mydict = {}
for index, line in enumerate(f3data):
cmyline = line.strip()
mydict[index] = cmyline
print mydict
Putting the words in a dict makes no sense. If you're using numbers as keys you should be using a list.
from __future__ import with_statement
with open('words.txt', 'r') as f:
lines = f.readlines()
words = {}
for n, line in enumerate(lines):
words[n] = line.strip()
print words

Categories

Resources