简体   繁体   中英

Iterating over a dictionary of list elements

I'm very new to Python (2.x) and trying to understand how to iterate over a dictionary containing multiple lists:

dict = {'list_1':[3, 'green', 'yellow', 'black'], 'list_2':[2, 'green', 'blue']}

I am trying to create a new list containing all of the unique values of these lists, but ignoring the first item (the integer). The result I'm looking for would be:

['green', 'yellow', 'black', 'blue']

Here is one of my many attempts. I'm quite lost, so if somebody could explain I would be most grateful.

newlist = []
for colors in dict.values() [1:]:
    if not colors in newlist:
        newlist.append(colors)

Use set.union :

>>> dic = {'list_1':[3, 'green', 'yellow', 'black'], 'list_2':[2, 'green', 'blue']}
>>> set().union(*(x[1:] for x in dic.itervalues()))
set(['blue', 'black', 'green', 'yellow'])

If a list is required simply pass this set to list() .

The working version of your attempt, though it is not efficient;

newlist = []
for colors in dic.values():
    lis = colors[1:]        #do slicing here
    for item in lis:
        if item not in newlist:
            newlist.append(item)
print newlist #['green', 'blue', 'yellow', 'black']

One way using itertools.chain to flatten the dict values into a single list then list comprehension to filter out the non-string values and finally set for the unique values:

In [1]: from itertools import chain
In [2]: dict={'list_1':[3,'green','yellow','black'],'list_2':[2,'green','blue']}
In [3]: set([x for x in chain(*dict.values()) if isinstance(x, str)])
Out[3]: set(['blue', 'black', 'green', 'yellow'])

If really want to remove the first item in the list only and not all ints then similarly you could do:

In [4]: set(chain(*[x[1:] for x in dict.itervalues()]))
Out[4]: set(['blue', 'black', 'green', 'yellow'])

The first answers fails if you want all ints not in the first position in the final set and second fails for none ints found at the first position so you should state what should happen for these cases.

This would work, even if you have integer at some other index:

>>> di = {'list_1':[3, 'green', 'yellow', 'black'], 'list_2':[2, 'green', 'blue']}
>>> set(x for value in di.values() for x in value if not isinstance(x, int))
set(['blue', 'black', 'green', 'yellow'])

If you print dict.values() , you get:

[[2, 'green', 'blue'], [3, 'green', 'yellow', 'black']]

Hence, when you're trying to slice it, you get:

[[3, 'green', 'yellow', 'black']]

Thus, you want to slice colors instead of the dict.values() :

for colors in t.values():
    colors = colors[1:]

Now there's another problem. You're checking if the list has been seen in the list, instead of each item. So you have to loop again .

for colors in t.values():
    colors = colors[1:]
    for color in colors:

Note that this can lead your script to not have such great performance, so you could probably do something like:

>>> from itertools import chain
>>> [i[1:] for i in t.values()]
[['green', 'blue'], ['green', 'yellow', 'black']]
>>> list(chain.from_iterable(i[1:] for i in t.values()))
['green', 'blue', 'green', 'yellow', 'black']

Therefore, integrated into your code:

new = set() # Better for performance to use sets
for color in chain.from_iterable(i[1:] for i in t.values()):
    if color not in new:
        new.add(color)

print new

Prints:

set(['blue', 'black', 'green', 'yellow']) # If you need order, use a list instead.

By the way, don't name a dictionary dict . It overrides the built-in type.

theColours = set()
for colours in d.values():
    [theColours.add(colour) for colour in colours[1:]]
list(theColours)

here's one-liner for you

>>> d = {'list_1':[3, 'green', 'yellow', 'black'], 'list_2':[2, 'green', 'blue']}
>>> list(set(i for x in d.itervalues() for i in x[1:]))
['blue', 'black', 'green', 'yellow']

As Haidro says, don't name a dictionary dict

创建一个删除重复项的set ,然后通过内置的sorted()运行它以返回列表。

newlist = sorted(set(dict.values()[1:]))

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