Python Forum
[solved] Variable number of dictionnaries as argument in def()
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[solved] Variable number of dictionnaries as argument in def()
#1
In the current code, I’m performing tests to works with a variable number of dictionaries; I’m looking for a way to get all keys and their values.

In the current example, especially in DictionnaryTest2 function, I fail in changing the tuple into the original list, in order to get key names (and an error is coming): I’m wondering if I’m using the right way (this is the first time) and so how to proceed?

Thanks for any advice

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np

# A dictionnary is created
n = 10
m = 1
X = np.random.random( (n,m) )
Y = np.random.random( (n,m) )
Z = np.random.random( (n,m) )
MyDictionnary = {'Abcissa': X, 'Ordinate': Y, 'Altitude': Z}
MyDictionnary2 = {'Abcissa2': X, 'Ordinate2': Y, 'Altitude2': Z, 'Theta': (X+Y)}
del X, Y, Z

# Dictionnary keys are listed / the dictionnary is explicitly expressed
KeyList0 = list(MyDictionnary.keys())
print("Key list (explicitly) : {}".format(KeyList0))


# Dictionnary keys are listed / the dictionnary name is a variable
MyVar = 'MyDictionnary'
KeyList1 = list(locals()[MyVar].keys())
print("Key list (name=variable) : {}".format(KeyList1))


# Now inside a function with the dictionnary in argument
def DictionnaryTest1(MyDict):
  NewVar = 'MyDict'
  KeyListFunction = list(locals()[NewVar].keys())
  print("Key list in a function : {}".format(KeyListFunction))
  return
  
KeyList1 = DictionnaryTest1(MyDictionnary)



# A list a dictionnary names is now created
DictionnaryNamesTables = ['MyDictionnary', 'MyDictionnary2']

# just for printing the dictionnaries list
for i in range(len(DictionnaryNamesTables)): 
  print(DictionnaryNamesTables[i])
  

def DictionnaryTest2(*args):

  # tests
  print("Type args = {}".format(type(args)))
  print("length args = {}".format(len(args)))
  print("args = {}".format(args))
  args = list(args)
  print("length args (after list())= {}".format(len(args)))
  NumberOfDictionnaries = len(args)
  
  for i in range(len(args)):
    NewVar = args[i]  #
    print("NewVar = {}".format(NewVar))
    KeyListFunction2 = list(locals()[NewVar].keys())
    print("KeyListFunction2 = {}".format(KeyListFunction2))

  return

KeyList2 = DictionnaryTest2(DictionnaryNamesTables)
Output:
Type args = <class 'tuple'> length args = 1 args = (['MyDictionnary', 'MyDictionnary2'],) length args (after list())= 1 NewVar = ['MyDictionnary', 'MyDictionnary2']
and the (logical) error
Error:
TypeError: unhashable type: 'list'
Reply
#2
What are you actually trying to achieve? I'm concerned about all this dynamic code creation you're doing - here using locals. Do you really need to be doing that? Code like that tends to be quite difficult to maintain.
Reply
#3
There are so many issues here
I think they want to unpack DictionnaryNamesTables in the function call
KeyList2 = DictionnaryTest2(*DictionnaryNamesTables)
Of course then they will hit scope issues because of using locals() - MyDictionnary is not defined inside the function scope.
Output:
Key list (explicitly) : ['Abcissa', 'Ordinate', 'Altitude'] Key list (name=variable) : ['Abcissa', 'Ordinate', 'Altitude'] Key list in a function : ['Abcissa', 'Ordinate', 'Altitude'] MyDictionnary MyDictionnary2 Type args = <class 'tuple'> length args = 2 args = ('MyDictionnary', 'MyDictionnary2') length args (after list())= 2 NewVar = MyDictionnary
Error:
Traceback (most recent call last): File "***", line *, in <module> KeyList2 = DictionnaryTest2(*DictionnaryNamesTables) File "***", line **, in DictionnaryTest2 KeyListFunction2 = list(locals()[NewVar].keys()) KeyError: 'MyDictionnary'
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#4
Dictionnaries names and numbers are variables, as well as for their keys ; using locals() is the only way I've found so far to not explicitly enter such informations.

Is it the best good way to do that? probably not, and I'm open to any suggestion to improve it in an efficient way Smile
Reply
#5
as mentioned by @ndc85430 it is unclear what are you actually trying to achieve

maybe something like this?
from itertools import chain
spam = {'foo':1, 'bar':2}
eggs = {'x':0, 'y':3}

dicts = [spam, eggs]

def get_keys(*args):
    for some_dict in args:
        print(list(some_dict.keys()))

def get_keys2(*args):
    print(list(chain(*args)))

get_keys(*dicts)
get_keys2(*dicts)
Output:
['foo', 'bar'] ['x', 'y'] ['foo', 'bar', 'x', 'y']
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
At least for such intent, I guess I figured out

Thanks

import numpy as np
from itertools import chain

# A dictionnary is created
n = 10
m = 1
X = np.random.random( (n,m) )
Y = np.random.random( (n,m) )
Z = np.random.random( (n,m) )
MyDictionnary = {'Abcissa': X, 'Ordinate': Y, 'Altitude': Z}
MyDictionnary2 = {'Abcissa2': X, 'Ordinate2': Y, 'Altitude2': Z, 'Theta': (X+Y)}
del X, Y, Z

# # Dictionnary keys are listed / the dictionnary is explicitly expressed
KeyList0 = list(MyDictionnary.keys())
print("Key list (explicitly) : {}".format(KeyList0))


## function get keys lists
def DictionnaryTest(*args):
    return(list(chain(*args)))

# A list of dictionnary names is now created
DictionnaryNamesTable = [MyDictionnary, MyDictionnary2]

KeyList2 = DictionnaryTest(*DictionnaryNamesTable)
print("Key list2 : {}".format(KeyList2))


## list composed of a single dictionnary
DictionnaryNamesTable = [MyDictionnary]
KeyList1 = DictionnaryTest(*DictionnaryNamesTable)
print("Key list1 : {}".format(KeyList1))
Reply
#7
(Apr-19-2021, 05:04 PM)paul18fr Wrote: Dictionnaries names and numbers are variables

Again, avoid doing this because that code is more difficult to read and harder to maintain. If you have a load of things that you need to use, then put those things in a collection as buran shows.
Reply
#8
Thumbs Up 
(Apr-20-2021, 05:28 AM)ndc85430 Wrote: Again, avoid doing this because that code is more difficult to read and harder to maintain. If you have a load of things that you need to use, then put those things in a collection as buran shows.

For sure your experiences and feedbacks are much greater than mine, so I'm seriously listening to your advices and warnings Smile .

I’m using dictionaries to record and store data where dictionaries are physical quantities and Keys are components for example; values are generally updated during the recording process; as you can imagine, their names, numbers, sizes and so on vary for each study.

I used locals(), globals(), exec() so far, but as you mentioned it should be avoided, and I’m working on a (good) way to remove them: even if I’m trying to well document my codes, maintainability is ones of the weakness.

In addition, I’m working in huge amount of data (the latest file I worked on as about 1 billion lines), it’s necessary to remain “fast” and so I want to read it only ounce (currently it takes few minutes for reading and storing) .. but I'm not perfect Big Grin
Reply
#9
(Apr-20-2021, 07:29 AM)paul18fr Wrote: I’m using dictionaries to record and store data where dictionaries are physical quantities and Keys are components for example; values are generally updated during the recording process; as you can imagine, their names, numbers, sizes and so on vary for each study.

(Apr-20-2021, 07:29 AM)paul18fr Wrote: I’m working in huge amount of data (the latest file I worked on as about 1 billion lines),
well, this screams you need database....
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#10
(Apr-20-2021, 09:03 AM)buran Wrote: well, this screams you need database....

Or I can store in hdf5 files (with h5py) and then work with 2D and 3D (numpy) arrays Wink
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [SOLVED] Pad strings to always get three-digit number? Winfried 2 340 Jan-27-2024, 05:23 PM
Last Post: Winfried
  TypeError: float() argument must be a string or a number, not 'list' Anldra12 2 4,852 Jul-01-2022, 01:23 PM
Last Post: deanhystad
  SOLVED variable as tuple name krayon70 7 1,809 Apr-09-2022, 03:30 PM
Last Post: krayon70
  Give a number for Variable quest 2 1,507 Jan-31-2022, 08:35 AM
Last Post: ibreeden
  Get latest version off website and save it as variable [SOLVED] AlphaInc 5 1,948 Nov-14-2021, 09:00 PM
Last Post: DeaD_EyE
  Adding an ascending number [SOLVED] AlphaInc 3 2,235 Jul-11-2021, 10:13 AM
Last Post: perfringo
  [solved] subdictionaries path as variable paul18fr 4 2,625 May-18-2021, 08:12 AM
Last Post: DeaD_EyE
  TypeError: int() argument must be a string, a bytes-like object or a number, not 'Non Anldra12 2 5,196 May-02-2021, 03:45 PM
Last Post: Anldra12
  Defining an object's argument whose name is stored in a variable arbiel 2 2,174 Dec-11-2020, 10:19 PM
Last Post: arbiel
  [regex] Good way to parse variable number of items? Winfried 4 2,611 May-15-2020, 01:54 PM
Last Post: Winfried

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020