Comparing Swift and Python Dictionary objects - python

I'm trying to get familiar with Swift, so I'm doing some basic computations that I would normally do in Python.
I want to get a value from a dictionary using a key. In Python I would simply :
sequences = ["ATG","AAA","TAG"]
D_codon_aa = {"ATG": "M", "AAA": "R", "TAG": "*"}
for seq in sequences:
print D_codon_aa[seq]
>>>
M
R
*
When I try this in Swift.
let sequences = ["ATG","AAA","TAG"]
let D_codon_aa = ["ATG": "M", "AAA": "R", "TAG": "*"]
for seq in sequences
{
var codon = D_codon_aa[seq]
println(codon)
}
>>>
Optional("M")
Optional("R")
Optional("*")
1) What is Optional() and why is it around the dictionary value?
2) Why can't I make a dictionary with multiple types of objects inside?
In Python I can do this:
sequence= {'A':0,'C':1, 'G':'2', 'T':3.0}
In Swift I can't do this:
let sequences = ["A":0,"C":1, "G":"2", "T":3.0]

1:
Look at the declaration of the dictionarys subscript:
subscript(key: Key) -> Value?
It returns an optional, since you can use any key you want in subscripts, but they might not associated with values, so in that case it returns nil, otherwise the value wrapped in an optional.
2: Actually, you can, if you define your dictionary as for eg. ["String": AnyObject], and now you can associate keys with values, thats conforms to the AnyObject protocol.
Updated
And your example let sequences = ["A":0,"C":1, "G":"2", "T":3.0] compiles fine in Xcode 6.1.1.

Related

Convert all values in dict to their actual type

Let's assume i have got this dictionary, filled with various string values:
dictionary = { "name": "Andrew", "age": "34", "is_good_enought": "True", "something": "None" }
How to convert all string values to their exact data type they represent?
Expected result:
dictionary = { "name": "Andrew", "age": 34, "is_good_enought": True, "something": None}
You could try something like:
from ast import literal_eval
for i, v in dictionary.items():
try:
dictionary[i] = literal_eval(v)
except ValueError:
pass
From the documentation:
ast.literal_eval(node_or_string)
Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.
You can do it by simply creating a function that filters the values given by the string, and typesetting them to their corresponding types. For example, like your example:
def change_type(string):
if string.lower() in ['true', 'false']: #for bool types
return string.lower()=='true'
elif string.isdigit(): #for int types
return int(string)
elif string.lower() == 'none': #For none-types
return None
else:
return string
Then, using your custom function, you can run:
for k, v in dictionary.items():
dictionary[k] = change_type(v)
For further filters, you can type help(str) and read on it, or you could use regex. Hope this helps.

Python set dictionary nested key with dot delineated string

If I have a dictionary that is nested, and I pass in a string like "key1.key2.key3" which would translate to:
myDict["key1"]["key2"]["key3"]
What would be an elegant way to be able to have a method where I could pass on that string and it would translate to that key assignment? Something like
myDict.set_nested('key1.key2.key3', someValue)
Using only builtin stuff:
def set(my_dict, key_string, value):
"""Given `foo`, 'key1.key2.key3', 'something', set foo['key1']['key2']['key3'] = 'something'"""
# Start off pointing at the original dictionary that was passed in.
here = my_dict
# Turn the string of key names into a list of strings.
keys = key_string.split(".")
# For every key *before* the last one, we concentrate on navigating through the dictionary.
for key in keys[:-1]:
# Try to find here[key]. If it doesn't exist, create it with an empty dictionary. Then,
# update our `here` pointer to refer to the thing we just found (or created).
here = here.setdefault(key, {})
# Finally, set the final key to the given value
here[keys[-1]] = value
myDict = {}
set(myDict, "key1.key2.key3", "some_value")
assert myDict == {"key1": {"key2": {"key3": "some_value"}}}
This traverses myDict one key at a time, ensuring that each sub-key refers to a nested dictionary.
You could also solve this recursively, but then you risk RecursionError exceptions without any real benefit.
There are a number of existing modules that will already do this, or something very much like it. For example, the jmespath module will resolve jmespath expressions, so given:
>>> mydict={'key1': {'key2': {'key3': 'value'}}}
You can run:
>>> import jmespath
>>> jmespath.search('key1.key2.key3', mydict)
'value'
The jsonpointer module does something similar, although it likes / for a separator instead of ..
Given the number of pre-existing modules I would avoid trying to write your own code to do this.
EDIT: OP's clarification makes it clear that this answer isn't what he's looking for. I'm leaving it up here for people who find it by title.
I implemented a class that did this a while back... it should serve your purposes.
I achieved this by overriding the default getattr/setattr functions for an object.
Check it out! AndroxxTraxxon/cfgutils
This lets you do some code like the following...
from cfgutils import obj
a = obj({
"b": 123,
"c": "apple",
"d": {
"e": "nested dictionary value"
}
})
print(a.d.e)
>>> nested dictionary value

Loop through dictionary keys to get values based on input

1) In my program I start with prompting a user for input.
2) I would then like to loop through the users input to get all the characters in that string, query each character individually against the dictionaries keys.
3) If a character from the input matches a key in the dictionary, I want that key's value returned.
4) This needs to be repeated for each character and the result should print those values returned in a string
To try and explain further, here is my dictionary:
dataDict = {
"a":"1",
"b":"2",
"c":"3",
}
For example:
If my input is abc, my result should be 123
If my input is cba, my result should be 321
and so on...
So far, this works if the string is only one character using the below code.
If i enter two characters, it just returns nothing.
dataInput=input("Enter stuff: ")
for key,value in dataDict.items():
if dataInput == key:
print(value)
How can I acheive the results i'm after?
You shouldn't be looping over the dict to find the matching keys, that's very inefficient. A dict is designed to do fast lookups: you give it the key and it gives you the value. Eg, dataDict["a"] results in "1".
Also, as Tim Pietzcker mentions, doing if dataInput == key will only work if dataInput consists of a single letter, because it compares the whole dataInput string to key.
Here's a simple way to do the desired conversion. We do the lookups in a list comprehension, which creates a list of the converted values, and then we pass that list to .join to create a string. (I've changed the names of your variables to conform with the PEP-008 style guide).
data_dict = {
"a": "1",
"b": "2",
"c": "3",
}
data_input = "aabbccba"
s = ''.join([data_dict[c] for c in data_input])
print(s)
output
11223321
However, that's not safe: it will fail with KeyError if data_input contains a char that's not in the dictionary. Here's a better way: it adds an empty string if it gets a bad char.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '') for c in data_input])
print(s)
output
11223321
Alternatively, we could convert bad data to some special value, eg 0.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '0') for c in data_input])
print(s)
output
11022303210
Just for fun, here's a "functional" version. Guido would probably not approve of this one. :)
data_input = "aaxbbcycbaz"
print(''.join(filter(None, map(data_dict.get, data_input))))
11223321
You should be iterating over the input string, not the dictionary. Also, you might want to use .get() in case the users enters a characters that's not in the dictionary:
for letter in dataInput:
print(dataDict.get(letter,"X"))
This will print each letter on its individual line. If you want to print them in a single line, you can add the end="" parameter to the print function (and print an empty line after you're done).
The comparison you're doing would never work (in the first iteration, it would amount to if "abc" == "a", I hope that makes it obvious).
You're iterating through the wrong thing. You should be iterating through the input. You don't need to iterate through the dict, because you can just look up by key.

Change json.dumps dictionary values in python

So i have following dict:
my_dict{'key1': 'value1',
'key2': 'value2',
'key3': json.dumps([
{"**subkey1**": "subvalue1", "**subkey2**": "subvalue2",},
{"**subkey1**": "other_subvalue", "**subkey2**":"other_subvalue2"}])
}
What I need is to somehow made a def where i have to check and for each subkey2 to change its value only for the def itself
And all subkey1 to check if its value is the same like the second subkey1
Please note I am talking about only subkey1 which I have twice.
I don't want to set them manually. Mean I have this dict global, and calling it from many def, so i need to make these changes and check inside each def
What I tried is:
def recurse_keys(my_dict, indent = ''):
print(indent+str(key))
if isinstance(my_dict[key], dict):
recurse_keys(my_dict[key], indent+' ')
recurse_keys(my_dict)
And for now it is only printing all of my params, but am not sure how to proceed
Example:
my_dict{'name': 'georgi',
'famili': 'ivanov',
'drinks': json.dumps([
{"breakfast": "milk", "lunch": "beer",},
{"breakfast": "tea", "lunch":"vodka"}])
def test()
....check if both breakfast are the same and if not make them so....(all these, mean dict and the function it self are in same file)
so I need to check if the values for the two breakfast are the same (without to know them) and if they are not, to make them so.
And also to check if there is lunch with empty value or 0 and again if not, to make it so
If you want to edit a json string, then probably the easiest way is to decode it to python data types d = json.loads(str), edit it, then encode it back to string str = json.dumps(d) (python JSON).
import json
my_dict = {'name': 'georgi',\
'famili': 'ivanov',\
'drinks': json.dumps([\
{"breakfast": "milk", "lunch": "beer",},\
{"breakfast": "tea", "lunch":"vodka"}])};
ddict = json.loads(my_dict["drinks"]) # json str to python data types
seen = {}; # store the items already seen
# for each dictionary object in key3
for d in range(0,len(ddict)):
for k in ddict[d]:
if k in seen:
# update the value to the one already seen
ddict[d][k] = seen[k];
if k == "lunch" and (ddict[d] == "" or ddict[d] is None):
ddict[d] = alternative_lunch_value;
else:
seen[k] = ddict[d][k];
my_dict["drinks"] = json.dumps(ddict);
print(my_dict);
The result on my machine is:
{'drinks': '[{"breakfast": "milk", "lunch": "beer"}, {"breakfast": "milk", "lunch": "beer"}]',
'famili': 'ivanov',
'name': 'georgi'}
Updating dict values
Because you wanted to update the values in my_dict so that it can be read by other modules, rather than just read the values. If all you wanted to do was read the values, then you can iterate over the list ddict as follows:
for value in ddict:
print("Sub1:{0} Sub2:{1}\n".format(value["**subkey1**"], value["**subkey2**"]));
However, since you want to update the values in the existing list, then you will need to iterate over a list of the indexes. As shown below...
Range() and len()
Range(start,end) gives a list with values from start to end. So a = range(1,4) assigns [1,2,3,4] to a. Also len(a) will return the number of items in the list, so 4 in this case. Using these principals, you can iterate through your ddict.
for d in range(1,len(ddict):
ddict[d]["**subkey1**"] = new_value;
Hope this helps get you started. If you update your question with more details on exactly what you want (i.e. example input and output, perhaps psudo code), then we will be able to give you a better answer.

Dictionary Operations... Index / Iterate / Validate

I'd like to:
Check a key / value at position i
Check to see if key / value contains a string
delete / store in another variable either the key / value
The equivelant of this Java code:
//Some list...
ArrayList<String> example;
...
//Index into data structure
example.get(i);
//Check for some string...
if (example.get(i).contains("someText")){
somestuff;
}
//Store in some other variable
exam = example.get(i)
That's what I'm effectively trying to in Java, however I'd like to be able to do that with Python dictionarties however I'm not sure if this is possible, as I find the Python documentation rather hard to read.
Python dictionaries are implemented as hash tables, so there is no intrinsic ordering; therefore, "position i" is a totally nonsensical concept for a dict -- it's like asking for the dict entry that's most yellow, or that least resembles a llama... those concepts just don't apply to dict entries, and "position i" is just as totally inapplicable.
Where does that i come from, i.e., what's the real issue you're trying to solve? If your requirement is to iterate over the dictionary, you do that directly, without the crutch of a "numeric index". Or, if you do need to keep some specific order or other, then you don't use a dict, but rather some different data structure. If you explain exactly the purpose you're trying to address, I'm sure we can help you.
Direct translation (for an ArrayList<String>, you do not want a dictionary, you want a list):
example = ["foo", "bar", "baz"]
str = example[i]
if "someText" in str:
somestuff()
Get used to the for keyword, though, it's awesome in Python:
for str in example:
if "someText" in str:
someStuff()
Here's an example using dictionaries:
fruits = {
"apple": "red",
"orange": "orange",
"banana": "yellow",
"pear": "green"
}
for key in fruits:
if fruits[key] == "apple":
print "An apple is my favorite fruit, and it is", fruits[key]
else:
print "A", key, "is not my favorite fruit, and it is", fruits[key]
Iteration using for on a dictionary results in the keys, it's still up to you to index the item itself. As Alex pointed out, we're really off-base answering you with so little information, and it sounds like you're not well-rooted in data structures (dictionaries will probably yield a different order every time you iterate it).
Yo can do that to reproduce the same behavior that your example in Java.
# Some list
example = {} # or example = dict()
...
# Index into data estructure.
example[example.keys(i)]
# Check for some string...
if example[example.keys(i)] == 'someText' :
pass
# Store in some other variable...
exam = example[example.keys(i)]
del example[example.keys(i)]
# ...or
exam = example.pop(example.keys(i))
What's nice about Python is that you can try code interactively.
So we create a list which is like a Java List:
>>> mylist = ["python","java","ruby"]
>>> mylist
['python', 'java', 'ruby']
We can get an entry in the list via its index:
>>> mylist[0]
'python'
And use the find function to search for substrings:
>>> mylist[1].find("av")
1
>>> mylist[1].find("ub")
-1
It returns -1 if the string isn't found.
Copying an entry to a new variable is done just how you'd expect:
>>> newvalue = mylist[2]
>>> newvalue
'ruby'
Or we can create a dict which is like a Java Map, storing by key rather than index, but these work very similarly to lists in Python:
>>> mydict = { 'python':'Guido', 'java':'James', 'ruby':'Yukihiro' }
>>> mydict['java']
'James'
>>> othervalue = mydict['ruby']
>>> othervalue
'Yukihiro'
>>> mydict['python'].find('uid')
1
>>> mydict['python'].find('hiro')
-1
>>> mydict['ruby'].find('hiro')
4

Categories