Concatenate iterator to variable name - python

I'd like to call a variable with a number in the name. I think the closest I've come is concatenating an iterator onto the name, and casting that as a dictionary but it doesn't work.
This is what I have tried:
dict0 = {"pet1":"dog", "pet2":"cat", "pet0":"bird"}
dict1 = {"first":"a", "second":"b", "third":"c"}
dict2 = {"num1":1,"num2":2,"num3":3}
for i in range(3):
tempDict = "dict"+str(i) # type is string
print(dict(tempDict))
output: ValueError: dictionary update sequence element #0 has length 1; 2 is required
These dictionaries are being populated with a database call, and the tables are numbered 0,1,2...n. Some days I have one dictionary, and some days multiple. It would be really convenient to be able to call them and act on the contents iteratively if possible. I'm not sure what to google for an answer, thank you in advance.

Assuming you have created the variables with the correct names (in this case dict0, dict1, dict2) you can get the values via their name using the vars() method
dict0 = {"pet1":"dog", "pet2":"cat", "pet0":"bird"}
dict1 = {"first":"a", "second":"b", "third":"c"}
dict2 = {"num1":1,"num2":2,"num3":3}
for i in range(3):
print(vars()[f"dict{i}"])
This prints each dict as expected

if you want to access dictionaries by their variable name try this:
dict0 = {"pet1":"dog", "pet2":"cat", "pet0":"bird"}
dict1 = {"first":"a", "second":"b", "third":"c"}
dict2 = {"num1":1,"num2":2,"num3":3}
for i in range(3):
dict_var_name = "dict"+str(i) # type is string
print(globals()[dict_var_name])
globals() return a dictionary which caontain all defined variables in global scope. for more information on this look at this question

Related

Pythonic way to populate a dictionary from list of records

Background
I have a module called db.py that is basically consist of wrapper functions that make calls to the db. I have a table called nba and that has columns like player_name age player_id etc.
I have a simple function called db_cache() where i make a call to the db table and request to get all the player ids. The output of the response looks something like this
[Record(player_id='31200952409069'), Record(player_id='31201050710077'), Record(player_id='31201050500545'), Record(player_id='31001811412442'), Record(player_id='31201050607711')]
Then I simply iterate through the list and dump each item inside a dictionary.
I am wondering if there is a more pythonic way to populate the dictionary?
My code
def db_cache():
my_dict: Dict[str, None] = {}
response = db.run_query(sql="SELECT player_id FROM nba")
for item in response:
my_dict[item.player_id] = None
return my_dict
my_dict = db_cache()
This is built-in to the dict type:
>>> help(dict.fromkeys)
Help on built-in function fromkeys:
fromkeys(iterable, value=None, /) method of builtins.type instance
Create a new dictionary with keys from iterable and values set to value.
The value we want is the default of None, so all we need is:
my_dict = dict.from_keys(db.run_query(sql="SELECT player_id FROM nba"))
Note that the value will be reused, and not copied, which can cause problems if you want to use a mutable value. In these cases, you should instead simply use the dict comprehension, as given in #AvihayTsayeg's answer.
my_arr = [1,2,3,4]
my_dict = {"item":item for item in my_arr}

Python Remove Duplicate Dict

I am trying to find a way to remove duplicates from a dict list. I don't have to test the entire object contents because the "name" value in a given object is enough to identify duplication (i.e., duplicate name = duplicate object). My current attempt is this;
newResultArray = []
for i in range(0, len(resultArray)):
for j in range(0, len(resultArray)):
if(i != j):
keyI = resultArray[i]['name']
keyJ = resultArray[j]['name']
if(keyI != keyJ):
newResultArray.append(resultArray[i])
, which is wildly incorrect. Grateful for any suggestions. Thank you.
If name is unique, you should just use a dictionary to store your inner dictionaries, with name being the key. Then you won't even have the issue of duplicates, and you can remove from the list in O(1) time.
Since I don't have access to the code that populates resultArray, I'll simply show how you can convert it into a dictionary in linear time. Although the best option would be to use a dictionary instead of resultArray in the first place, if possible.
new_dictionary = {}
for item in resultArray:
new_dictionary[item['name']] = item
If you must have a list in the end, then you can convert back into a dictionary as such:
new_list = [v for k,v in new_dictionary.items()]
Since "name" provides uniqueness... and assuming "name" is a hashable object, you can build an intermediate dictionary keyed by "name". Any like-named dicts will simply overwrite their predecessor in the dict, giving you a list of unique dictionaries.
tmpDict = {result["name"]:result for result in resultArray}
newArray = list(tmpDict.values())
del tmpDict
You could shrink that down to
newArray = list({result["name"]:result for result in resultArray}.values())
which may be a bit obscure.

How do i retrieve the variable name for each dict in a list of dicts?

I may be missing something fundamental here but consider the following:
graph=nx.read_graphml('path here...')
dDict=dict(nx.degree_centrality(graph)) #create dict
lDict=dict(nx.load_centrality(graph))
new_lists=[dDict,lDict]
for i in new_lists:
print().... #how to get variable name i.e. dDict
how do i iterate through the list of dicts so that when i do a print it returns me the variable name the dict equals i.e. i want to be able to retrieve back 'dDict' and 'lDict'?I do not want a quick hack such as
dDict['name'] = 'dDict'
Any ideas..?
EDIT: the reason i want to do this is so that i can append these centrality measures to a dataframe with new column name i.e.:
for idx in range(len(new_lists)):
for i in range(len(df)):
rowIndex = df.index[i]
df.loc[rowIndex, idx] = new_lists[idx][rowIndex] #instead of idx how do i dynamically name the column according to the list item name.
You can iterate over globals() and get the variable name of the object that matches the content you are looking for.
More info on https://docs.python.org/3/library/functions.html?highlight=globals#globals
However, this is a rather cumbersome trick, you should not do that! Rather, redesign your software so you don't have to look for the variable names in the first place.
def get_var_name_of(x):
return [k for k,v in globals().items() if v==x][0]
dDict = {1:'asd'}
lDict = {2:'qwe'}
new_list=[dDict,lDict]
for d in new_list:
print(get_var_name_of(d))
dDict
lDict

Create variable number of dictionary with name taken from list in Python

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()')

Python: Convert a String into a tuple or list with a twist

I have a set of data that looks like so:
OutletCntrTemp|25degreesC|ok
InletTemp|17degreesC|ok
PCHTemp|46degreesC|ok
P0ThermMargin|-57degreesC|ok
P1ThermMargin|-59degreesC|ok
P0DIMMTemp|27degreesC|ok
P1DIMMTemp|27degreesC|ok
HSC0InputPower|60Watts|ok
HSC0InputVolt|12.46Volts|ok
CPU0Tjmax|90degreesC|ok
......
Now I want to loop through this data and create a list or a tuple in a function and return each row but name that tuple using the first part of the string:
CPUTjmax = ('90degreesC','ok')
now i did some spliting up of the string via | but hit a wall when i tried to use string[0] = (string[1],string[2]) to define the tuple.
Could anyone give me a pointer here please.
Ric
What you can do is, create a dict, and add them as key:value pair in it:
>>> d = dict()
>>>
>>> s = 'CPU0Tjmax|90degreesC|ok'
>>> li = s.split("|")
>>>
>>> d[li[0]] = (li[1], li[2])
>>> d
{'CPU0Tjmax': ('90degreesC', 'ok')}
You almost certainly don't want to create variables, use a dict instead:
data = [
'CPU0Tjmax|90degreesC|ok',
'InletTemp|17degreesC|ok'
]
d = {el[0]: tuple(el[1:]) for el in (item.split('|') for item in data)}
# {'InletTemp': ('17degreesC', 'ok'), 'CPU0Tjmax': ('90degreesC', 'ok')}
The other answers are good. Here is one more way, similar to the answer using locals(). You just create an empty object, and fill its __dict__:
class X(object):
pass
Var = X()
for ...:
Var.__dict__[string[0]] = (string[1], string[2])
#now you can refer to your vars as Var.whatever
if Var.InletTemp[1] != 'ok':
...
Use should definitely use a dictionary variable.
For completeness here a non-standard solution for creating new local variables:
for line in open("data.dat"):
e=line.split("|")
locals()[e[0]] = ( e[1], e[2] )
Internally, the local variables are also a dictionary which you can access with locals().
However, as the documentation says:
The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

Categories

Resources