I have the following string :
str = "{application.root.category.id:2}"
I would like to convert the above to a dictionary data type in python as in :
dict = {application.root.category.id:2}
I tried using eval() and this is the error I got:
AttributeError: java package 'application' has no attribute "root"
My current python is of <2.3 and I cannot update the python to >2.3 .
Any solutions ?
Python dictionaries have keys that needn't be strings; therefore, when you write {a: b} you need the quotation marks around a if it's meant to be a string. ({1:2}, for instance, maps the integer 1 to the integer 2.)
So you can't just pass something of the sort you have to eval. You'll need to parse it yourself. (Or, if it happens to be easier, change whatever generates it to put quotation marks around the keys.)
Exactly how to parse it depends on what your dictionaries might actually look like; for instance, can the values themselves be dictionaries, or are they always numbers, or what? Here's a simple and probably too crude approach:
contents = str[1:-1] # strip off leading { and trailing }
items = contents.split(',') # each individual item looks like key:value
pairs = [item.split(':',1) for item in items] # ("key","value"), both strings
d = dict((k,eval(v)) for (k,v) in pairs) # evaluate values but not strings
First, 'dict' is the type name so not good for the variable name.
The following, does precisely as you asked...
a_dict = dict([str.strip('{}').split(":"),])
But if, as I expect, you want to add more mappings to the dictionary, a different approach is required.
Suppose I have a string
str='{1:0,2:3,3:4}'
str=str.split('{}')
mydict={}
for every in str1.split(','):
z=every.split(':')
z1=[]
for every in z:
z1.append(int(every))
for k in z1:
mydict[z1[0]]=z1[1]
output:
mydict
{1: 0, 2: 1, 3: 4}
Related
1) My goal is to create a sequence that is a list that contains ordered dictionaries. The only problem for me will be described below.
I want the list to represent a bunch of "points" which are for all intents and purposes just an ordered dictionary. However, I notice that when I use OrderedDict class, when I print the dictionary it comes up as OrderedDict([key value pair 1, key value pair 2, ... etc)] For me, I would rather it behave like an ordered dictionary, BUT not having those DOUBLE "messy/ugly" "end marks" which are the "[( )]". I don't mind if the points have ONE, and only one, type of "end marks". Also I would also like it if when I print this data type that stuff like OrderedDict() doesn't show up. However, I do not mind if it shows up in return values. Like you know how when you print a list it doesn't show up as list(index0, index1, ... etc) but instead it shows up as [index0, index1, ... etc]. That is what I mean. Inside the point, it would look like this
point = {'height': 1, 'weight': 3, 'age': 5, etc} <- It could be brackets or braces or parentheses. Just some type of "end mark", but I preferably would like it to be in {} and having key value pairs indicated by key: value and have them separated by commas.
what_i_am_looking_for = [point0, point1, point2, point3, ... etc]
In Python 3.6, the ordinary dict implementation was re-written and maintains key insertion order like OrderedDict, but was considered an implementation detail. Python 3.7 made this feature an official part of the language spec, so if you use Python 3.6+ just use dict instead of OrderedDict if you don't care about backward-compatibility with Python 3.5 or earlier.
my_dict = dict([(1,'apple'), (2,'ball')])
when I print my_dict the output is
{1: 'apple', 2: 'ball'}
How it's working?
I am new to python Please explain this
Thanks in advance!
Dictionary is data structure in Python. Think about it as an unordered(after python3.7 can be ordered) set of key: value pairs.
The values of a dictionary can be of any type, keys must be of an immutable data type such as strings, numbers, or tuples.
In your command, dict() used as constructor and values([(1,'apple'), (2,'ball')]) is an iterable object.
Each item in the iterable is itself an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.
Here is different representation of your example:
list_of_tuples = [(1,'apple'), (2,'ball')]
in order to create a dictionary, program will need to iterate thru the each value in the list_of_tuples
thats why you can use dict() constructor to do it, like so:
my_dict = dict(list_of_tuples)
Note that if a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary.
When you create a dictionary you do with curly brackets, {}, with the keys and values separated by colons, :. Here's an example
my_dict = {
1 : 'apple',
2 : 'ball'
}
You can index this dictionary with square brackets as you've done in the question.
When you call print on this dictionary it prints it out in a similar fashion with the key followed a colon and the value, all encompassed within curly brackets.
{1: 'apple', 2: 'ball'}
If you would like to print a particular value in the dictionary you do so as follows
print my_dict[1]
This would print out the value associated with 1 in the dictionary which in our example is
apple
I want to replace letters in a character vector by other ones, using a dictionary created with dict, as follows
import string
trans1 = str.maketrans("abc","cda")
trans = dict(zip("abc","cda"))
out1 = "abcabc".translate(trans1)
out = "abcabc".translate(trans)
print(out1)
print(out)
The desired output is "cdacda"
What I get is
cdacda
abcabc
Now out1 is this desired output, but out is not. I can not figure out why this is the case. How can I use the dictionary created via dict in the translate function? So what do I have to change if I want to use translate with trans?
str.translate supports dicts perfectly well (in fact, it supports anything that supports indexing, i.e. __getitem__) – it's just that the key has to be the ordinal representation of the character, not the character itself.
Compare:
>>> "abc".translate({"a": "d"})
'abc'
>>> "abc".translate({ord("a"): "d"})
'dbc'
I do not think the method translate will accept a dictionary object. Aditionlly, you should look at what you are creating:
>>> dict(zip("abc","cda"))
{'c': 'a', 'a': 'c', 'b': 'd'}
I do not think that is what you wanted. zip pairs off correspondingly indexed elements from the first and second argument.
You could write a work around:
def translate_from_dict(original_text,dictionary_of_translations):
out = original_text
for target in dictionary_of_translations:
trans = str.maketrans(target,dictionary_of_translations[target])
out = out.translate(trans)
return out
trans = {"abc":"cda"}
out = translate_from_dict("abcabc",trans)
print(out)
Usage of the dict function to create the dictionary. Read the function definition.
>>> dict([("abc","cda")])
{"abc":"cda"}
The string.translate doesn't support dictionaries as arguments:
translate(s, table, deletions='')
translate(s,table [,deletions]) -> string
Return a copy of the string s, where all characters occurring
in the optional argument deletions are removed, and the
remaining characters have been mapped through the given
translation table, which must be a string of length 256. The
deletions argument is not allowed for Unicode strings.
So, you have to write your own function.
Also, revise your code as it wont run in any python version that I know. It has at least 2 exceptions.
I'm I need to slice the leading character off the valued a dictionary - but only if the length of the value is greater than 1. Currently I'm doing this with a dictionary comprehension:
new_dict = {item[0]:item[1][1:] for item in old_dict if item.startswith('1')}
but I don't know how to modify this so that keys of length one are left alone.
The keys are the codewords of a Huffman code, and so start with '0' or '1'.
An example code is:
code = {'a':'0', 'b':'10', 'c':'110', 'd':'111'}
The above code works fine for 'b','c','d' but fails for 'a' (this is intensional - it's a unit test).
How do I correctly modify the above example to pass the test?
The nature of a comprehension is that it builds a new object iteratively, so you if you want every key in the original object old_dict to have a corresponding key in new_dict, you simply have to process every key.
Also, you say "I need to slice the leading character off the keys a dictionary", but the code you give slices the leading characters off the values. I assume you mean values. I suggest the following:
new_dict = {key:(value[:1] if len(value) > 1 else value) for key,value in old_dict.iteritems()}
Apart from using sequence assignment to make the iteration a bit clearer, I've used the if expression (equivalent to ternary operator in c-like languages) to incorporate the condition.
I've also dropped your original if clause, because I don't understand you to want to skip values starting with '1'.
I'm not sure which variable is where but you could do something along these lines.
new_dict = { item[0]:item[1][1] if len(item[1]) > 1 else item[0]:item[1] for item in old_dict if item.startswith('1') }
If I understand your question correctly, you can accomplish it with this:
new_dict = {k:v[len(v)>1:] for k,v in old_dict.items()}
v[len(v)>1] will return the key if it is only 1 character, and it will strip off the leading character if it is more than one character
I'm not sure what you are trying to accomplish with if item.startswith('1') is a qualifier for your list comprehension but if you need it you can add it back on. May need to make it v.startswith('1') though.
Is it possible to use strings as indices in an array in python?
For example:
myArray = []
myArray["john"] = "johns value"
myArray["jeff"] = "jeffs value"
print myArray["john"]
What you want is called an associative array. In python these are called dictionaries.
Dictionaries are sometimes found in other languages as “associative memories” or “associative arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys.
myDict = {}
myDict["john"] = "johns value"
myDict["jeff"] = "jeffs value"
Alternative way to create the above dict:
myDict = {"john": "johns value", "jeff": "jeffs value"}
Accessing values:
print(myDict["jeff"]) # => "jeffs value"
Getting the keys (in Python v2):
print(myDict.keys()) # => ["john", "jeff"]
In Python 3, you'll get a dict_keys, which is a view and a bit more efficient (see views docs and PEP 3106 for details).
print(myDict.keys()) # => dict_keys(['john', 'jeff'])
If you want to learn about python dictionary internals, I recommend this ~25 min video presentation: https://www.youtube.com/watch?v=C4Kc8xzcA68. It's called the "The Mighty Dictionary".
Even better, try an OrderedDict (assuming you want something like a list). Closer to a list than a regular dict since the keys have an order just like list elements have an order. With a regular dict, the keys have an arbitrary order.
Note that this is available in Python 3 and 2.7. If you want to use with an earlier version of Python you can find installable modules to do that.