Python Forum
Variable Substitution call keys
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Variable Substitution call keys
#1
I have a dictionary: new_dict
I have a string variable with the path to a nested dictionary called patho is set to:

['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']

I want to issue new_dict+$patho.keys which should come out to:

new_dict['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE'].keys

I tried several ways to use the patho variable to substitute. Nothing working. Keep getting syntax errors
Reply
#2
If pathio is truly just a string, you'd need to parse the string for all the keys. Can you print the string to show the exact contents? And why do you have the string in that format?

Once parsed, you can recursively follow your nested dict to find the final one in the path. Also the package python-benedict seems to have methods for accessing paths into a nested dict directly.
Gribouillis likes this post
Reply
#3
(Aug-26-2024, 07:15 PM)bowlofred Wrote: If pathio is truly just a string, you'd need to parse the string for all the keys. Can you print the string to show the exact contents? And why do you have the string in that format?

Once parsed, you can recursively follow your nested dict to find the final one in the path. Also the package python-benedict seems to have methods for accessing paths into a nested dict directly.

I had posted the contents of patho.............

['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']

This works, If I hard code that after the dictionary name it works. Now I want to accommodate for all the other Queues I will be getting.
Reply
#4
(Aug-26-2024, 08:30 PM)Bobbee Wrote:
(Aug-26-2024, 07:15 PM)bowlofred Wrote: If pathio is truly just a string, you'd need to parse the string for all the keys. Can you print the string to show the exact contents? And why do you have the string in that format?

Once parsed, you can recursively follow your nested dict to find the final one in the path. Also the package python-benedict seems to have methods for accessing paths into a nested dict directly.

I had posted the contents of patho.............

['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']

This works, If I hard code that after the dictionary name it works. Now I want to accommodate for all the other Queues I will be getting.

I see your other question.

['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']

is the format you append to the dictionary name before .key to specify a nested dictionary. This is a PRINT statement that is working in the code.

print("-----Keys of SYSTEM.ADMIN.COMMAND.QUEUE = ", new_test_dict['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE'].keys())
Reply
#5
Quote:is the format you append to the dictionary name before .key to specify a nested dictionary.
Not quite right.

new_test_dict is a dictionary.
new_test_dict['PCFData'] returns the value associated with the key 'PCFData' in new_test_dict. The value must be a dictionary because you use "Q_STATISTICS_DATA" to index the value.

You are not "appending" a "format" to the dictionary name. You are "indexing" a dictionary using a key. Maybe it is more clear when written this way.
temp = new_test_dict['PCFData']
temp = temp['Q_STATISTICS_DATA']
temp = temp['SYSTEM.ADMIN.COMMAND.QUEUE']
print(temp.keys())
I looked at the python-benedict package mention by bowlofred. I don't think that would work because you have "." in some of your dictionary keys (i.e. 'SYSTEM.ADMIN.COMMAND.QUEUE). That was an unfortunate choice.

This is an unfriendly format. Difficult to parse.
Quote:['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']
I would pick something like this.
Quote:'PCFData|Q_STATISTICS_DATA|SYSTEM.ADMIN.COMMAND.QUEUE'
Then you could use something like I posted in your other thread.

https://python-forum.io/thread-42716-pos...#pid180738
class PathDictionary:
    def __init__(self, dictionary):
        self.dictionary = dictionary
 
    def __getitem__(self, path):
        value = self.dictionary
        for part in path.split("|"):   # Choose a separator that is not found in any of the keys.
            value = value[part]
        return value
To use:
cmdq = 'PCFData|Q_STATISTICS_DATA|SYSTEM.ADMIN.COMMAND.QUEUE'
pathdict = PathDictionary(new_data_dict)
print(pathdict[cmdq].keys())
Reply
#6
(Aug-26-2024, 09:44 PM)deanhystad Wrote:
Quote:is the format you append to the dictionary name before .key to specify a nested dictionary.
Not quite right.

new_test_dict is a dictionary.
new_test_dict['PCFData'] returns the value associated with the key 'PCFData' in new_test_dict. The value must be a dictionary because you use "Q_STATISTICS_DATA" to index the value.

You are not "appending" a "format" to the dictionary name. You are "indexing" a dictionary using a key. Maybe it is more clear when written this way.
temp = new_test_dict['PCFData']
temp = temp['Q_STATISTICS_DATA']
temp = temp['SYSTEM.ADMIN.COMMAND.QUEUE']
print(temp.keys())
I looked at the python-benedict package mention by bowlofred. I don't think that would work because you have "." in some of your dictionary keys (i.e. 'SYSTEM.ADMIN.COMMAND.QUEUE). That was an unfortunate choice.

This is an unfriendly format. Difficult to parse.
Quote:['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']
I would pick something like this.
Quote:'PCFData|Q_STATISTICS_DATA|SYSTEM.ADMIN.COMMAND.QUEUE'
Then you could use something like I posted in your other thread.

https://python-forum.io/thread-42716-pos...#pid180738
class PathDictionary:
    def __init__(self, dictionary):
        self.dictionary = dictionary
 
    def __getitem__(self, path):
        value = self.dictionary
        for part in path.split("|"):   # Choose a separator that is not found in any of the keys.
            value = value[part]
        return value
To use:
cmdq = 'PCFData|Q_STATISTICS_DATA|SYSTEM.ADMIN.COMMAND.QUEUE'
pathdict = PathDictionary(new_data_dict)
print(pathdict[cmdq].keys())

This is the full data stream so you get what I am parsing. I have it working. just nee to concatenate

new_test_dict with a string variable containing
['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']
and '.keys'

It works when it is hard-coded. But I have a LIST of those paths and want to iterate through the list sub'ing the path values in the list into the .keys and .value extraction.

{'reason': 'NONE', 'MQMD': {'StrucId': 'MD', 'Version': 1, 'Report': 'NONE', 'MsgType': 'DATAGRAM', 'Expiry': -1, 'Feedback': 'NONE', 'Encoding': 546, 'CodedCharSetId': 1208, 'Format': 'MQADMIN', 'Priority': 0, 'Persistence': 'NOT_PERSISTENT', 'MsgId': '0x414d5120424f424245453220202020200e57ba66feed0840', 'CorrelId': '0x000000000000000000000000000000000000000000000000', 'BackoutCount': 0, 'ReplyToQ': '', 'ReplyToQMgr': 'BOBBEE2', 'UserIdentifier': '', 'AccountingToken': '0x0000000000000000000000000000000000000000000000000000000000000000', 'ApplIdentityData': '', 'PutApplType': 'QMGR', 'PutApplName': 'BOBBEE2', 'PutDate': '20240826', 'PutTime': '16115225', 'ApplOriginData': '', 'GroupId': '0x000000000000000000000000000000000000000000000000', 'MsgSeqNumber': 1, 'Offset': 0, 'MsgFlags': 0, 'OriginalLength': -1}, 'PCFheader': {'Type': 'STATISTICS', 'StrucLength': 36, 'Version': 3, 'Command': 'STATISTICS_Q', 'MsgSeqNumber': 1, 'Control': 'LAST', 'CompCode': 0, 'Reason': 0, 'ParameterCount': 8, 'sReason': 'NONE'}, 'PCFData': {'Q_MGR_NAME': 'BOBBEE2', 'START_DATE': '2024-08-26', 'START_TIME': '09.10.52', 'END_DATE': '2024-08-26', 'END_TIME': '09.11.52', 'COMMAND_LEVEL': 940, 'OBJECT_COUNT': 1, 'Q_STATISTICS_DATA': {'SYSTEM.ADMIN.COMMAND.QUEUE': {'Q_NAME': 'SYSTEM.ADMIN.COMMAND.QUEUE', 'CREATION_DATE': '2023-04-18', 'CREATION_TIME': '12.32.19', 'Q_TYPE': 'LOCAL', 'DEFINITION_TYPE': 'PREDEFINED', 'Q_MIN_DEPTH': 0, 'Q_MAX_DEPTH': 0, 'AVG_Q_TIME': [0, 0], 'PUTS': [9, 0], 'PUTS_FAILED': 0, 'PUT1S': [0, 0], 'PUT1S_FAILED': 0, 'PUT_BYTES': [728, 0], 'GETS': [9, 0], 'GET_BYTES': [728, 0], 'GETS_FAILED': 0, 'BROWSES': [0, 0], 'BROWSE_BYTES': [0, 0], 'BROWSES_FAILED': 0, 'MSGS_NOT_QUEUED': 9, 'MSGS_EXPIRED': 0, 'MSGS_PURGED': 0}}}, 'time': '2024-08-26 16:24:11.910772', 'delta': '0:00:00'}
Method 1 - Using keys() method:
['reason', 'MQMD', 'PCFheader', 'PCFData', 'time', 'delta']
Reply
#7
I think this problem may have a solution that has nothing to do with your current approach. Please describe what your program should accomplish, not how you want think it should be accomplished.
What information are you trying to extract from the dictionary? Can you provide multiple examples of the "paths" you are trying to make?
Reply
#8
(Aug-27-2024, 03:18 AM)deanhystad Wrote: I think this problem may have a solution that has nothing to do with your current approach. Please describe what your program should accomplish, not how you want think it should be accomplished.
What information are you trying to extract from the dictionary? Can you provide multiple examples of the "paths" you are trying to make?

Right now my solution:
1 - Takes the data from an incoming stream.
2 - have a cursive routine the looks for 'Q_NAME' key, embedded in a Nest Dictionary and returns the paths to all appearances. I end up with a list of paths
3 - I have that path hard coded, for now, extracting the keys and values to the Nested Dictionary Q_NAME resides in.
4 - I append the values to a CSV file which builds by day.

everything is working as expected. What I originally asked. Is there a way, in step #3 to use variable substitution to iterate through the LIST of paths to automate this.

Right now I have:

for x in QNAME_LIST:
recurse_object(new_test_dict, x) # returns global variable patho
keys_string = new_test_dict['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE'].keys()
value_string = new_test_dict['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE'].values()

I would like to be able to replace the hard coded path (ie ['PCFData']['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']) which is the contents of the variable 'patho' with a variable substitution using patho.

Again, this is all working. I am having difficulties getting the variable substitution to work so something like this.

keys_string = new_test_dict%patho%.keys() or keys_string = new_test_dict$[patho].keys()

I have looked and things I find don't seem to work. this should be easy.
Reply
#9
It would be nice if I could pull off something like this.

print("-----Keys using patho = ", new_test_dict + str(patho).keys())

BUT......

AttributeError: 'str' object has no attribute 'keys'
Reply
#10
Why are you doing str(patho)? What is patho?

And do you really need patho, or QNQME_LIST? Why not have the routine that creates QNAME_LIST do the work (get keys and values)?

Would you post your code please, not just little pieces.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  not able to call the variable inside the if/elif function mareeswaran 3 752 Feb-09-2025, 04:27 PM
Last Post: mareeswaran
  Need help with for loop and variable value substitution in a function rsurathu 2 3,237 Jul-21-2020, 06:47 AM
Last Post: rsurathu
  Simple automated SoapAPI Call with single variable replacement from csv asaxty 1 2,934 Jun-30-2020, 06:38 PM
Last Post: asaxty
  Bytearray substitution Vismuto 1 3,571 Apr-14-2020, 09:18 AM
Last Post: TomToad
  Substitution with regular expression returns hidden character SOH bajacri 2 5,008 Nov-17-2019, 03:38 AM
Last Post: bajacri
  variable call back into an array yamifm0f 3 3,257 Jun-07-2019, 02:44 PM
Last Post: heiner55
  Reference new dictionary keys with a variable slouw 4 4,122 May-07-2019, 03:30 AM
Last Post: slouw
  Call a variable jmf08 16 8,443 Jan-18-2019, 05:50 AM
Last Post: jmf08
  call a variable from one function to another ... evilcode1 4 5,125 Sep-16-2018, 10:50 AM
Last Post: gruntfutuk
  How to call a variable declared in a function in another python script lravikumarvsp 2 3,766 Jun-04-2018, 08:45 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

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