I am trying to use a dictionary in such a way so that it returns a value dynamically. The following code should print "hello" first, then "world". As of now, it prints "hello" two times. Is there a way for me to use this dictionary dynamically?
val = "hello"
test = {
"A" : val
}
print(test["A"])
val="world"
print(test["A"])
I am thinking that this is not correct use of dictionaries. Could you please the whole task?
You can also check values and change the dictionary value
val = "hello"
test = {
"A" : val
}
print(test["A"])
val="world"
if test["A"]!=val: test["A"]=val
print(test["A"])
instead of val="world" use test["A"] = "world"
val = "world" assigns a new string to the variable, but doesn't change the existing string. The dictionary test however keeps the old string value, not a reference to the val variable. You need to use another mutable data structure if you want to update the dictionary like this. Just for illustration, I show how a list would work:
val = ["hello"]
test = { "A" : val }
print(test["A"][0])
val[0] = "world"
print(test["A"][0])
Unlike a string, a list can be updated. test keeps the same (list) value as val (there is only one list in this example), but val is changed internally.
Note that you must not use val = ["world"], as this would again just assign a new list to val, but leave test unchanged, i.e. still refer to the old list containing "hello".
Related
First I tried directly storing values from a list having the name 'data' in an array variable 'c' using loop but 'none' got printed
for i in data:
print(i['name'])
c=i['name']
Here print(i['name']) perfectly worked and output appeared
This is the working ouput
Then I printed c in order to print the values generated using loop. The ouput came as none.
print(c)
Then I tried another way by storing the values and making the array iterable at the same time using for loop. An error occurred which I was unable to resolve.
for i in data:
b[c]=i['name']
c=c+1
The error apeared is as follow-
I have tried two ways, if there is any other way please help me out as I am new to python.
It looks like the variable 'data' is a dictionary.
If you want to add each name from that dictionary to a list:
# create a new list variable
names = []
for i in data:
name = i['name']
print(name)
# add the name to the list
names.append(name)
# output the new list
print(names)
Assuming your data object here is a list like [{"name": "Mr. Green", ...}, {"name": "Mr. Blue", ...}].
If your goal is to end up with c == ["Mr. Green", "Mr. Blue"], then you're looking for something like:
c = []
for i in data:
c.append(i['name'])
print(c)
or you can accomplish tasks like these using list comprehensions like:
c = [i['name'] for i in data]
print(c)
The first code example you posted is iterating through the items in data and reassigning the value of c to each item's name key - not adding them to a list("array"). Without knowing more about the code you ran to produce the screenshot and/or the contents of data, it's hard to say why you're seeing print(c) produce None. I'd guess the last item in data is something like {"name": None, ...} which if it's coming from JSON is possible if the value is null. Small note: I'd generally use .get("name") here instead so that your program doesn't blow up if an item is missing a "name" key entirely.
For your second code example, the error is different but I think falls along a similar logical fallacy which is that lists in python function differently from primitives(things like numbers and strings). For the interpreter to know that b or c are supposed to be lists("arrays"), they need to be instantiated differently and they have their own set of syntax/methods for mutation. For example, like arrays in other languages, lists are indexed by position so doing b[c] = <something> will only work if c is an integer. So something similar to your second example that would also produce a list of names like my above would be:
b = [None] * len(data)
c = 0
for i in data:
b[c]=i['name']
c=c+1
Note that if you only initialize b = [], you get an IndexError: list assignment index out of range on the initial assignment of b[0] = "some name" because the list is of size 0.
Add
b = []
above your first line of code. As the error is saying that you have not (and correctly so) defined the list to append.
I personally would use list comprehension here
b = [obj['name'] for obj in data]
where obj is i as you have defined it.
This question already has answers here:
Access nested dictionary items via a list of keys?
(20 answers)
Closed 2 years ago.
Apologies if this is really simple, but I can't seem to get it going.
My application is working with nested dicts. For example: -
test = {
"alpha": "first",
"beta": {
"mid": {
"message": "winner winner"
}
},
"omega": "last"
}
Now I need to be able retrieve values out of that dict using variable the value of which is being dynamically constructed based on myriad other factors. So essentially I'm trying to put together a way to generate the key that I need depending on variable factors.
For example if I get back from one function "beta", from another, "mid" and from another "message", the best I can think to do is assemble a string which looks like the key path.
So for example:
current = '["beta"]["mid"]["message"]'
How can I use current to get back the "winner winner" string?
I have tried things like:-
v = '"[beta"]["mid"]"message]"'
print(test[v])
But just hitting Key errors.
Must be an easy way to get values based on calculated keys. Would appreciate a shove in the right direction.
[Question text updated]
Yes, I know I can do:
val = test['beta']['mid']['message']
And get back the value, I'm stuck on how to use the generated string as the the key path. Apologies for not being clear enough.
import re
t = '["beta"]["mid"]["message"]'
val = None
for i in re.findall(r'"([^"]+)"', t):
if(val == None):
val = test.get(i)
else:
val = val.get(i)
print(val)
or,
from functools import reduce
import operator
import re
t = '["beta"]["mid"]["message"]'
reduce(operator.getitem, re.findall(r'"([^"]+)"', t), test)
winner winner
Store the three keys as three different variables rather than as a string:
key_one = 'beta'
key_two = 'mid'
key_three = 'message'
v = test[key_one][key_two][key_three]
If you already have the keys in the string format you describe, then do some string splitting to produce three variables like the above. You don't want to eval the code as it creates a security risk.
current = '["beta"]["mid"]["message"]'
keys = [w.strip('[]"') for w in current.split('"]["')]
test[keys[0]][keys[1]][keys[2]]
# or
# key_one = keys[0]
# key_two = keys[1]
# key_three = keys[2]
# v = test[key_one][key_two][key_three]
This should do it:
v = test['beta']['mid']['message']
print(v)
Note: The issue is you're indexing the dictionary with a string in your example, not a set of keys.
I have an array in which has multiple objects inside it, I want to parse it to give me the value of bar that is in each object.
This is a mock of the array/object I am trying to parse to get the values from.
[
{
foo: [
{
bar: 50,
crow: true
}
]
}
...
{}
...
]
So far this is as far as I have come on the code and admittedly it isn't very far as I've been back tracking as things go wrong and worse.
for foo in response:
print foo
foo_list = list(foo)
print(foo_list[0])
This outputs the whole value of foo then it outputs only the key foo
PS I know this is a repeat question, please only mark as so if the repeat one has the exact format I am looking for.
You want something along the lines of
something[0]['foo'][0]['bar']
The '[' means you need to access an element of a list. The [0] gets the first element of a list.
The '{' means you need to access an entry of a dictionary. The ['foo'] means get the value of key 'foo'.
Your sample above has a dict in a list in a dict in a list.
You should also not scrimp when it comes to error checking... The above could easily be:
sentinel = object() # unique object for checking default from get()
bar = None
if isinstance(something, list) and len(something) == 1:
elem = something[0]
if isinstance(elem, dict):
val = elem.get('foo', sentinel)
if val is not sentinel:
# and so on and so on...
The other thing to mention is that sometimes you don't care about the name of the key. Instead of saying dick.get(key), which requires knowing the key, you can say dick.values()[0]
So, the top could also be:
something[0].values()[0][0].values()[0]
Again, don't skimp on the error checking...
I'm going to assume you want the inner values. Try this code:
response = [{'foo': [ { 'bar': 50, 'crow': True } ] }]
for i in range(len(response)):
for key in response[i].keys():
for d in response[i][key]:
print(list(d.values()))
Basically, what's happening here is we're first iterating through the outer list ([]), then iterating the keys in that array, then iterating each item in that value list for key foo, then printing a list of the dictionary's values. You could also just grab the whole dict as d.
Also, if this is JSON, you're going to want to parse it first with the json lib. See https://docs.python.org/3/library/json.html for more information on that.
I am using a new script (a) to extract information from an old script (b) to create a new file (c). I am looking for an equal sign in the old script (b) and want to modify the modification script (a) to make it automated.
The string is
lev1tolev2 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
It is written in python 3.
The current output is fixed at
cam2map from=e119-b3331l1 to=rsmap-x map=enc.Ink.map pixres=mpp defaultrange=MAP res=300 minlat=-71.5 maxlat=90 minlon=220 maxlon=360
Currently, I have the code able to export a string of 0.6 for all of the iterations of lev1tolev2, but each one of these is going to be different.
cam2map = Call("cam2map")
cam2map.kwargs["from"] = old_lev1tolev2.kwargs["from"]
cam2map.kwargs["to"] = "rsmap-x"
cam2map.kwargs["map"] = "enc.Ink.map"
cam2map.kwargs["pixres"] = "mpp"
cam2map.kwargs["defaultrange"] = "MAP"
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
cam2map.kwargs["minlat"] = lat[0]
cam2map.kwargs["maxlat"] = lat[1]
cam2map.kwargs["minlon"] = lon[0]
cam2map.kwargs["maxlon"] = lon[1]
I have two questions, why is this not converting the string to a float? And, why is this not iterating over all of the lev1tolev2 commands as everything else in the code does?
The full code is available here.
https://codeshare.io/G6drmk
The problem occurred at a different location in the code.
def escape_kw_value(value):
if not isinstance(value, str):
return value
elif (value.startswith(('"', "'")) and value.endswith(('"', "'"))):
return value
# TODO escape the quote with \" or \'
#if value.startswith(('"', "'")) or value.endswith(('"', "'")):
# return value
if " " in value:
value = '"{}"'.format(value)
return value
it doesn't seem to clear to me, but from you syntax here :
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
I'd bet that cam2map.kwargs["res"] is a dict, and you thought that it would convert every values in the dict, using the ** syntax. The float built-in should then be called in a loop over the elements of the dict, or possible a list-comprehension as here :
cam2map.kwargs["res"] = dict()
for key, value in old_lev1tolev2.kwars["res"].items():
cam2map.kwargs["res"][key] = float(value)
Edit :
Ok so, it seems you took the string 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
And then thought that calling youstring.kwargs would give you a dict, but it won't, you can probably parse it to a dict first, using some lib, or, you use mystring.split('=') and then work your way to a dict first, like that:
output = dict()
for one_bit in lev_1_lev2.split(' '):
key, value = one_bit.split('=')
output[key] = value
I have a list which grows and shrinks in a for loop. The list looks like following :- . With every element inside list of list i want to associate it to a separate dictionary.
list123 = [[1010,0101],[0111,1000]]
In this case I want to create 4 dictionary with the following name
dict1010 = {}
dict0101 = {}
dict0111 = {}
dict1000 = {}
I tried following loop
for list1 in list123:
for element in list1:
dict + str(element) = dict()
This is the error i am getting
SyntaxError: can't assign to literal
while you can dynamically create variables, unless there is an overwhelming need to do that use instead a dictionary of dictionary witch key is the name you want, like this
my_dicts=dict()
for list1 in list123:
for element in list1:
my_dicts["dict" + str(element)] = dict()
and to access one of them do for example my_dicts["dict1010"]
You can uses globals() function to add names to global namespace like this
for list1 in list123:
for element in list1:
globals()["dict"+str(element)] = {}
this will add variables with the names you want as if you created them using dictx={} also numbers that begins with 0 won't convert well using str() so you should make your list a list of strings
First of all, I must say that you shouldn't do this. However, if you really want to, you can use exec.
If you really want to do this, you could use exec:
list123 = [[1010,0101],[0111,1000]]
for list1 in list123:
for element in list1:
var = 'dict' + str(element)
exec(var + ' = dict()')