简体   繁体   中英

Different list values for dictionary keys

I created a dictionary, where the key is a tuple of 3 elements and the value is a list, as so:

dic = {}
l = []

for z in range(0,20):
    for y in range(0,150):
        for x in range(0,200):
            for j in range(0,4):
                l.append(self.images[j].GetScalarComponentAsDouble(x, y, z, 0))
            dic.update({(x,y,z) : l})

print(dic[(25,25,5)])

images is just a list of image data, from where I get the intensity value and store this value in list l .

The final result I want to see in the dictionary will have items in this form:

{(...),
 (150,120,10): [2,5,3,9], 
 (130,100,16): [4,1,1,8],
(...)}

But because the list is always being appended with elements without being reseted, I cannot obtain this result.

How can I reset the list l so that every tuple key has its own list value?

There is an alternative way to write this, using itertool 's product function and list comprehensions:

from itertools import product

dic = {}
for z, y, x in product(range(20), range(150), range(200)):
    dic[x, y, z] = [self.images[j].GetScalarComponentAsDouble(x, y, z, 0)
                     for j in range(4)]

Functions in itertools often help you avoid deep nesting, and the list comprehension allows you to create the list and assign it to the dictionary in one line (although I broke out into two for readability in this example).

Actually, since python dictionaries are unordered, assuming your GetScalarComponentAsDouble doesn't have any side effects, changing the loop order of x, yz makes the code easier to follow while producing the same output.

from itertools import product

dic = {}
for x, y, z in product(range(200), range(150), range(20)):
    dic[x, y, z] = [self.images[j].GetScalarComponentAsDouble(x, y, z, 0)
                     for j in range(4)]

You can use this code:

dic = {}

for z in range(0,20):
    for y in range(0,150):
        for x in range(0,200):
            l = []
            for j in range(0,4):
                l.append(self.images[j].GetScalarComponentAsDouble(x, y, z, 0))
            dic.update({(x,y,z) : l})

print(dic[(25,25,5)])

To make your life a bit easier, you can use defaultdict from the collections module, initialized with a list for this case. This an a good example of their use-case:

from collections import defaultdict

dict = defaultdict(list)  # initialize with list for values

This will create an empty list [] for each dictionary entry you create, then you can just append to this list while you create the keys . For your case, this means that in your final for loop you can just append the self.image directly in the dictionary:

for j in range(0,4):
    dict[(x, y, z)].append(self.images[j].GetScalarComponentAsDouble(x, y, z, 0))

This removes the need for that list variable l all together.


The other way is to simply initialize a new list before the for loop where you actually use the list:

for x in range(0,200):
    l = []  # create new list
    for j in range(0,4):
        l.append(self.images[j].GetScalarComponentAsDouble(x, y, z, 0))
    dic.update({(x,y,z) : l})

This will achieve the same thing but it will include two generally unnecessary statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM