I need a dictionary that has two keys with the same name, but different values. One way I tried to do this is by creating a class where I would put the each key name of my dictionary, so that they would be different objects:
names = ["1", "1"]
values = [[1, 2, 3], [4, 5, 6]]
dict = {}
class Sets(object):
def __init__(self,name):
self.name = name
for i in range(len(names)):
dict[Sets(names[i])] = values[i]
print dict
The result I was expecting was:
{"1": [1, 2, 3], "1": [4, 5, 6]}
But instead it was:
{"1": [4, 5, 6]}
[EDIT]
So I discovered that keys in a dictionary are meant to be unique, having two keys with the same name is a incorrect use of dictionary. So I need to rethink my problem and use other methods avaliable in Python.
What you are trying to do is not possible with dictionaries. In fact, it is contrary to the whole idea behind dictionaries.
Also, your Sets class won't help you, as it effectively gives each name a new (sort of random) hash code, making it difficult to retrieve items from the dictionary, other than checking all the items, which defeats the purpose of the dict. You can not do dict.get(Sets(some_name)), as this will create a new Sets object, having a different hash code than the one already in the dictionary!
What you can do instead is:
Just create a list of (name, value) pairs, or
pairs = zip(names, values) # or list(zip(...)) in Python 3
create a dictionary mapping names to lists of values.
dictionary = {}
for n, v in zip(names, values):
dictionary.setdefault(n, []).append(v)
The first approach, using lists of tuples, will have linear lookup time (you basically have to check all the entries), but the second one, a dict mapping to lists, is as close as you can get to "multi-key-dicts" and should serve your purposes well. To access the values per key, do this:
for key, values in dictionary.iteritems():
for value in values:
print key, value
Instead of wanting multiple keys with the same name, could you getting away of having multiple values per each key?
names = [1]
values = [[1, 2, 3], [4, 5, 6]]
dict = {}
for i in names:
dict[i] = values
for k,v in dict.items():
for v in dict[k]:
print("key: {} :: v: {}".format(k, v))
Output:
key: 1 :: v: [1, 2, 3]
key: 1 :: v: [4, 5, 6]
Then you would access each value like this (or in a loop):
print("Key 1 value 1: {}".format(dict[1][0]))
print("Key 1 value 2: {}".format(dict[1][1]))
Related
i have a 300 frames from a video in format name_numberofFrame, i created a dictionary with key as name and value to key as list of number of frame but this list is not sorted i want it to be sorted to perform some other operations.
please provide me a way to sort that list?
It's not that difficult. You can access each value inside this dictionary and sort it. Like this:
a={'a':[4,2,1], 'v':[41,5,1]}
for i,j in a.items():
a[i]=sorted(a[i])
print(a)
Output:
{'a': [1, 2, 4], 'v': [1, 5, 41]}
I hope this is what you were looking for.
Say I have two dictionaries:
dict_one = {abc: 5, bat: 1, car: 6, xray: 3}
dict_two = {abc: 2, jfk: 4, zit: 7}
I want to compare the keys of both and create a new dictionary which contains only the keys of dict_one which don't occur in dict_two.
The new dictionary would look like this:
unique_dict = {bat: 1, car: 6, xray: 3}
This is what I am trying at the moment (the first part found here: Python read two dictionaries compare values and create third dictionary)
However I know the problem is that I can't update(key, value) as it takes only one argument, but I just don't know how to do this correctly.
d1_values = set(dict_one.keys())
d2_values = set(dict_two.keys())
words_in_both = d1_values & d2_values
not_in_both = d1_values ^ d2_values
unique_dict = {}
for key, value in dict_one.items():
for word in words_in_both:
if key != word:
unique_dict.update(key, value) # this is not correct
You could use the following dictionary comprehension to keep the key/value pairs in dict_one if they are not in dict_two:
{k:v for k,v in dict_one.items() if k not in dict_two}
# {'bat': 1, 'car': 6, 'xray': 3}
Sets and dict views already support subtraction to keep only the values in the left hand side not found in the right. So your code could simplify to:
{k: dict_one[k] for k in dict_one.keys() - dict_two.keys()}
yatu's answer is probably better in this specific case (no set temporary required), but I figured I'd point out set/view subtraction as well as showing no conversion to set itself is necessary (views can be used as set-like objects already).
def filter_dicts(d1, d2):
"""Return d1 items that are not in d2"""
return {title: value for title, value in d1.items() if title not in d2}
Sorry the topic's title is vague, I find it hard to explain.
I have a dictionary in which each value is a list of items. I wish to remove the duplicated items, so that each item will appear minimum times (preferable once) in the lists.
Consider the dictionary:
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}
'weapon2' and 'weapon3' have the same values, so it should result in:
result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2]}
since I don't mind the order, it can also result in:
result_dictionary = {"weapon1":[1],"weapon2":[2],"weapon3":[3]}
But when "there's no choice" it should leave the value. Consider this new dictionary:
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]}
now, since it cannot assign either '2' or '3' only once without leaving a key empty, a possible output would be:
result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2],"weapon4":[3]}
I can relax the problem to only the first part and manage, though I prefer a solution to the two parts together
#!/usr/bin/env python3
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}
result = {}
used_values = []
def extract_semi_unique_value(my_list):
for val in my_list:
if val not in used_values:
used_values.append(val)
return val
return my_list[0]
for key, value in example_dictionary.items():
semi_unique_value = extract_semi_unique_value(value)
result[key] = [semi_unique_value]
print(result)
This is probably not the most efficient solution possible. Because it involves iteration over all possible combinations, then it'll run quite slow for large targets.
It makes use of itertools.product() to get all possible combinations. Then in it, tries to find the combination with the most unique numbers (by testing the length of a set).
from itertools import product
def dedup(weapons):
# get the keys and values ordered so we can join them back
# up again at the end
keys, vals = zip(*weapons.items())
# because sets remove all duplicates, whichever combo has
# the longest set is the most unique
best = max(product(*vals), key=lambda combo: len(set(combo)))
# combine the keys and whatever we found was the best combo
return {k: [v] for k, v in zip(keys, best)}
From the examples:
dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 3}
dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 2, 'weapon4': 3}
this could help
import itertools
res = {'weapon1': [1, 2, 3], 'weapon2': [2, 3], 'weapon3': [2, 3]}
r = [[x] for x in list(set(list(itertools.chain.from_iterable(res.values()))))]
r2 = [x for x in res.keys()]
r3 = list(itertools.product(r2,r))
r4 = dict([r3[x] for x in range(0,len(r3)) if not x%4])
I want to copy pairs from this dictionary based on their values so they can be assigned to new variables. From my research it seems easy to do this based on keys, but in my case the values are what I'm tracking.
things = ({'alpha': 1, 'beta': 2, 'cheese': 3, 'delta': 4})
And in made-up language I can assign variables like so -
smaller_things = all values =3 in things
You can use .items() to traverse through the pairs and make changes like this:
smaller_things = {}
for k, v in things.items():
if v == 3:
smaller_things[k] = v
If you want a one liner and only need the keys back, list comprehension will do it:
smaller_things = [k for k, v in things.items() if v == 3]
>>> things = { 'a': 3, 'b': 2, 'c': 3 }
>>> [k for k, v in things.items() if v == 3]
['a', 'c']
you can just reverse the dictionary and pull from that:
keys_values = { 1:"a", 2:"b"}
values_keys = dict(zip(keys_values.values(), keys_values.keys()))
print values_keys
>>> {"a":1, "b":2}
That way you can do whatever you need to with standard dictionary syntax.
The potential drawback is if you have non-unique values in the original dictionary; items in the original with the same value will have the same key in the reversed dictionary, so you can't guarantee which of the original keys would be the new value. And potentially some values are unhashable (such as lists).
Unless you have a compulsive need to be clever, iterating over items is easier:
for key, val in my_dict.items():
if matches_condition(val):
do_something(key)
kindly this answer is as per my understanding of your question .
The dictionary is a kind of hash table , the main intension of dictionary is providing the non integer indexing to the values . The keys in dictionary are just like indexes .
for suppose consider the "array" , the elements in array are addressed by the index , and we have index for the elements not the elements for index . Just like that we have keys(non integer indexes) for values in dictionary .
And there is one implication the values in dictionary are non hashable I mean the values in dictionary are mutable and keys in dictionary are immutable ,simply values could be changed any time .
simply it is not good approach to address any thing by using values in dictionary
What's the best way to initialize (e.g. before a loop) a dictionary that will contain strings and a list in each item?
For instance:
dict = [("string1", [1,2]), ("string2", [5,6]),..]
So:
dict["string1"]
returns:
[1,2]
Please don't call a variable dict (or list, or set, etc) because it "covers up" existing functions and prevents you from using them.
data = {
"string1": [1,2],
"string2": [5,6]
}
print data["string1"] # => [1,2]
If you're a bit of a masochist, you can also try
data = dict([("string1",[1,2]), ("string2", [5,6])])
or (per cval's example)
data = dict(zip(strings, numbers))
Just pass the list to the dict() function, it'll return a dictionary, and never use dict as a variable name:
>>> dic = [("string1", [1,2]), ("string2", [5,6])]
>>> dict(dic)
{'string2': [5, 6], 'string1': [1, 2]}
Python 2.7 and Python 3, dict comprehension:
data = {entry[0]: entry[1] for entry in data}
or unpack your structures:
data = {k: v for (k, v) in data}
Python 2.6 and before, generator expression:
data = dict((entry[0], entry[1]) for entry in data)
or again unpack:
data = dict((k, v) for (k, v) in data)
Since your data is already in the form of (key, value) sequences, you can just generate a dict in one go by passing the structure to the dict type without an explicit dict or generator expression:
dict(data)
strings = ["string1","string2"]
numbers = [[1, 2], [5, 6]]
data = {k:v for k,v in zip(strings, numbers)}
And I don't recommend using reserved words (such as dict) as variable names.