I can't seem to get a comma embedded string (i.e. an LDIF DN value) to save as a key in an associative list without the value being interpreted as a list itself. I can't find a method that will cause the value of the string variable to be interpreted intact with the commas. I've verified that the "dn" variable is typed as a string.

Here is a snippet of my code:

for (dn, entry) in result_set[i]: results[dn]['printerName'] = entry['printerName'][0] [\code]

Results in a Keyerror over the "dn" variable:

KeyError: 'CN=REHP004,OU=servers,DC=example,DC=com'

Sorry, I'm a python newb. I hope this makes sense.[code=python]
for (dn, entry) in result_set:
results[dn] = entry[0]

Results in a Keyerror over the "dn" variable:

KeyError: 'CN=REHP004,OU=servers,DC=example,DC=com'

Sorry, I'm a python newb. I hope this makes sense.

Quick tip: Use the (code) button which will tip the '/' in the closing tag the right way. To get inline code samples (see below), use begin tag (CODE) and end tag (/ICODE)

What type is results? A list cannot work with non-integer index. My error was TypeError: list indices must be integers, not str that was with results = [] ... results[dn] = 'dummy value'. When I replace that with results = {} ... results[dn] = 'dummy value' things worked just fine.

Debugging suggestion when you get inexplicable compiler errors: Start with something bogus and simple such as I did. One at a time add bits of complexity until you get to the needed result.

Thanks for the quick tip.

Here is how I'm initializing/declaring "results": results = {None:{None:None}} I'm not accustomed to the py-terminology yet. I guess what I'm trying to accomplish is a dictionary inside a dictionary, where the top level key reference is the embedded comma value.

Here is my test script. I was successful for the straight forward assignment, but I'm not getting it on the multi-dimensional scenario.

#! /bin/env python

from pprint import pprint

dn1 = 'ou=something,ou=elsewhere,dc=example,dc=com'
dn2 = 'ou=something2,ou=elsewhere,dc=example,dc=com'
dn3 = 'ou=something3,ou=elsewhere,dc=example,dc=com'

val1 = 'junk'
val2 = 'junk2'
val3 = 'junk3'

# Simple assignment
result = {}
result[dn1] = val1

# Complex assignment
#result = {None:{None:None}}
#result[dn1]['xyz'] = val1
#result[dn2]['xyz'] = val1
#result[dn3]['xyz'] = val1


The pprint output from the above code looks like:

{'ou=something,ou=elsewhere,dc=example,dc=com': 'junk'}

When commenting the "simple case" and uncommenting the "complex case" this is the result:

Traceback (most recent call last):
  File "./test1.py", line 19, in ?
    result[dn1]['xyz'] = val1
KeyError: 'ou=something,ou=elsewhere,dc=example,dc=com'

Python is a not a strictly typed language, so Python doesn't know what the "type" of the value is (it doesn't know anything about type until it runs), so you can't "pre declare" it, you just put into the value what is needed. So starting at your line 18 you should have something like:

result = {}
result[dn1] = {'xyz':val1}

Note that this is probably not production quality (what if dn1 is seen again? This code overwrites the first with the second, which might be the right thing)

It appears that I have to decompose the inner dictionary in order to append to it on each key/value pair being added to it then replace the inner dictionary after it has been separately appended. This is what I wound up with:

#! /bin/env python

from pprint import pprint

result = {}
dnlist = ['ou=a,ou=elsewhere,dc=example,dc=com','ou=b,ou=elsewhere,dc=example,dc=com','ou=c,ou=elsewhere,dc=example
keylist = ['abc', 'def', 'ghi', 'jkl']
vallist = ['a', 'b', 'c', 'd']

for d in dnlist:
   i = 0
   j = len(keylist)
   print "j = %d" % j
   while(i < j):
      print "d = %s - i = %d" % (d,i)
      key = keylist[i]
      val = vallist[i]
      if result.has_key(d):
         tmp1 = result[d]
         tmp1[key] = val
         result[d] = tmp1
         result[d] = {key: val}
      i += 1


This produced this:

j = 4
d = ou=a,ou=elsewhere,dc=example,dc=com - i = 0
d = ou=a,ou=elsewhere,dc=example,dc=com - i = 1
d = ou=a,ou=elsewhere,dc=example,dc=com - i = 2
d = ou=a,ou=elsewhere,dc=example,dc=com - i = 3
j = 4
d = ou=b,ou=elsewhere,dc=example,dc=com - i = 0
d = ou=b,ou=elsewhere,dc=example,dc=com - i = 1
d = ou=b,ou=elsewhere,dc=example,dc=com - i = 2
d = ou=b,ou=elsewhere,dc=example,dc=com - i = 3
j = 4
d = ou=c,ou=elsewhere,dc=example,dc=com - i = 0
d = ou=c,ou=elsewhere,dc=example,dc=com - i = 1
d = ou=c,ou=elsewhere,dc=example,dc=com - i = 2
d = ou=c,ou=elsewhere,dc=example,dc=com - i = 3
{'ou=a,ou=elsewhere,dc=example,dc=com': {'abc': 'a',
                                         'def': 'b',
                                         'ghi': 'c',
                                         'jkl': 'd'},
 'ou=b,ou=elsewhere,dc=example,dc=com': {'abc': 'a',
                                         'def': 'b',
                                         'ghi': 'c',
                                         'jkl': 'd'},
 'ou=c,ou=elsewhere,dc=example,dc=com': {'abc': 'a',
                                         'def': 'b',
                                         'ghi': 'c',
                                         'jkl': 'd'}}

Many thanks for your help.

Yep, that works. There are a couple of things that might streamline your code just a bit: Given a dict d, you can do these things: actualvalue = d.setdefault(key,defaultvalue) which is particularly useful if the defaultvalue is a dict or list, because you can use it like d.setdefault(key,{})[secondarykey]=secondaryvalue This actually inserts key and defaultvalue into d.

In a similar vein, you can use this: actualvalue = d.get(key,defaultvalue) which does not insert the default value, but does return it if the key is not in the dictionary.

idiom: if d.has_key(k): ... is often written as if k in d: ...

Again, thanks for your valuable help. I really appreciate your thoughts and techinques. I did play with the "setdefault" method a bit, but didn't seem to get it wooled around correctly. I'll go back and try your suggestion for d.setdefault(key,{})[secondarykey]=secondaryvalue . Using the setdefault method would be a cleaner route to go.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.18 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.