Question

I'm trying to extend a dict value into a list in python 2.6 When i run the extend i'm not getting all dictionary values into the list. What am i missing?

def cld_compile(ru,to_file,cld):
    a = list()
    p = subprocess.Popen(ru, shell=True, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    a = p.stdout.readlines()
    p.wait()
    if (p.returncode != 0):
        os.remove(to_file)
        clderr = dict()
        clderr["filename"] = cld
        clderr["errors"] = a[1]
    return clderr




def main():
    clderrors = list()
    <removed lines>
    cldterr = cld_compile(ru,to_file,cld)
    clderrors.extend(cldterr)

Return value of cldterr:

print cldterr
{'errors': 'fail 0[file.so: undefined symbol: Device_Assign]: library file.so\r\n', 'filename': '/users/home/ili/a.pdr'}

When i attempt to extend cldterr to the list clderrors i only get:

print clderrors
['errors', 'filename']
Was it helpful?

Solution 2

dict.__iter__ runs through all the KEYS of the dictionary without giving the values, so for something like:

d = {'a':1, 'b':2, 'c':3}
for element in d:
    print(element)
# "a"
# "b"
# "c"

That's why list.extend is only giving you the keys "errors" and "filename". What would you LIKE it to give you, is the better question? I'm not even sure how that should be expected to work -- maybe a tuple of (key,value)? To do that, access dict.items() which will give you a dict_items object that yields (key,value) each iteration:

To use the same example:

for element in d.items():
    print(element)
# ("a",1)
# ("b",2)
# ("c",3)

Or in your case:

for key,value in cldterr.items():
    clderrors.append((key,value))

# or if you want future programmers to yell at you:
# [clderrors.append(key,value) for key,value in cldterr.items()]
# don't use list comps for their side effects! :)

Or simply:

clderrors.extend(cldterr.items())

OTHER TIPS

It it because .extend() expects a sequence, you want to use append() which expects an object.

For example

>>> l = list()
>>> d = dict('a':1, 'b':2}
>>> l.extend(d)
['a', 'b']

>>> l2 = list()
>>> l2.append(d)
[{'a':1, 'b':2}]

In Python when you iterate over a dictionary you get it's keys as a sequence, hence when using extends() only the dictionary keys are added to the list - as Python is asking for the same iterator we get when iterating over the dictionary in a for loop.

>>> for k in d:
        print k
a
b

Yes. it is expected, when you access dictionary by it's name, it would iterate over keys only. If you want dictionary values to be in list, you can do:

errList={'errors': 'fail 0[file.so: undefined symbol: Device_Assign]: library file.so\r\n', 'filename': '/users/home/ili/a.pdr'}
l= [(i +" "+ d[i]) for i in errList]
print l 

Otherwise, you can access dictionary as list of tuples:

print errList.items()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top