Iteration Through tuple of dictionaries in Python - python

I am trying to iterate through a tuple of dictionaries using Python, get the value that I'm looking for and then modify another dictionary with that value. Example:
Dict = {'1': 'one', '2': 'three'}
Tuple = ({'1': 'one', '5': 'five'}, {'4': 'four', '2': 'two'})
My goal is to modify Dict and replace 'three' with 'two' from my second dictionary in my tuple.
I know how to iterate through dictionaries using for loops and dict.items(), but i can't seem to do so with tuple...
Any help will be much appreciated!

Just check each dict d for the key and then set Dict["2"] equal to d["2"].
Dict = {'1': 'one', '2': 'three'}
Tuple = ({'1': 'one', '5': 'five'}, {'4': 'four', '2': 'two'})
for d in Tuple:
if "2" in d:
Dict["2"] = d["2"]
If you have multiple dicts in Tuple that have the same key the value will be set to the last dict you encounter. If you wanted the first match you should break in the if.
Dict = {'1': 'one', '2': 'three'}
Tuple = ({'1': 'one', '5': 'five'}, {'4': 'four', '2': 'two'})
for d in Tuple:
if "2" in d:
Dict["2"] = d["2"]
break # get first match
If you want the last match it would be better start at the end of Tuple:
for d in reversed(Tuple):
if "2" in d:
Dict["2"] = d["2"]
break # last dict in Tuple that has the key

Related

Python - Sort Dictionary Key Alphabetically while sorting Value list elements by length

I have a Dictionary here:
test_dict = {'gfg': ['One', 'six', 'three'],
'is': ['seven', 'eight', 'nine'],
'best': ['ten', 'six']}
I tried:
for i in range(len(test_dict)):
values = list(test_dict.values())
keys = list(test_dict)
value_sorted_list = values[i]
value_sorted_list = keys[i]
keys_sorted_list = random.shuffle(value_sorted_list)
test_dict.update({f"{keys_sorted_list}":value_sorted_list})
I want to sort the keys alphabetically while the value list by length
Something like this:
test_dict = {'best': ['six', 'ten'],
'gfg': ['One', 'six', 'three'],
'is': ['nine', 'eight', 'seven]}
I also want another function similar to the one i mentioned above but if the elements are similar length, to sort them randomly.
As well as another function to sort value list randomly.
Sorting keys alphabetically and values by length.
new_dict = {}
for key in sorted(test_dict.keys()):
sorted_values = sorted(test_dict[key], key=len)
new_dict[key] = sorted_values
print(new_dict)
This can be achieved with a dictionary comprehension as follows:
test_dict = {'gfg': ['One', 'six', 'three'],
'is': ['seven', 'eight', 'nine'],
'best': ['ten', 'six']}
new_dict = {k:sorted(v, key=len) for k, v in sorted(test_dict.items())}
print(new_dict)
Output:
{'best': ['ten', 'six'], 'gfg': ['One', 'six', 'three'], 'is': ['nine', 'seven', 'eight']}
dict preserves insertion order since 3.7.
Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.
Therefore, you can simply construct a new dictionary according to the sorted key and ensure the corresponding value is sorted. From the output your posted, the value is sorted by length first then alphabetically.
result = {key: sorted(value, key=lambda x: (len(x), x)) for key, value in sorted(test_dict.items())} # Thanks to Masklinn
print(result)
# {'best': ['six', 'ten'], 'gfg': ['One', 'six', 'three'], 'is': ['nine', 'eight', 'seven']}
Reference:
dict-comprehension - a way to construct a dictionary
sorted - The key function here achieves sorting by length first then alphabetically. You can change it according to your sorting rules.

Python: select key, values from dictionary corresponding to given list

I have a set dictionary like so:
d = {'cat': 'one', 'dog': 'two', 'fish': 'three'}
Given a list, can I just keep the key, values given?
Input:
l = ['one', 'three']
Output:
new_d = {'cat': 'one', 'fish': 'three'}
You can use dictionary comprehension to achieve this easily:
{k: v for k, v in d.items() if v in l}
The scenario you've described above provides a perfect use case for the IN operator, which tests whether or not a value is a member of a collection, such as a list.
The code below is to demonstrate the concept. For more practical applications, look at dictionary comprehension.
d = {'cat': 'one', 'dog': 'two', 'fish': 'three'}
l = ['one', 'three']
d_output = {}
for k,v in d.items(): # Loop through input dictionary
if v in l: # Check if the value is included in the given list
d_output[k] = v # Assign the key: value to the output dictionary
print(d_output)
Output is:
{'cat': 'one', 'fish': 'three'}
You can copy your dictionary and drop unwanted elements:
d = {'cat': 'one', 'dog': 'two', 'fish': 'three'}
l = ['one', 'three']
new_d = d.copy()
for element in d:
if (d[element]) not in l:
new_d.pop(element)
print(d)
print(new_d)
Output is:
{'cat': 'one', 'dog': 'two', 'fish': 'three'}
{'cat': 'one', 'fish': 'three'}

How can you partition every value of a dictionary and change that value to the first output?

Let's say I have the dict:
dict = {
'1': 'robert; james; pasta',
'2': 'peas; cupcake; happy times; peas'}
the dict would have multiple pairs so you need to go through them all
I need to get it to go through them all and transform it to:
dict = {
'1': 'robert',
'2': 'peas'}
how could I do this? I know you need to use partition.
I tried:
for i in questionanswerclean.values():
ram = i.partition(';')
print(i)
questionanswerclean[i] = ram
This ovewrites dic with the same dictionary where each value is the first one of the string when you split at ;.
Note: Don't name your dictionary dict because that's a language built-in name.
dic = {
'1': 'robert; james; pasta',
'2': 'peas; cupcake; happy times; peas'
}
dic = {key: val.split(';')[0] for key, val in dic.items()}
print(dic)
Output:
{'1': 'robert', '2': 'peas'}
indeed your approach was correct, you just needed to use [] to access the first item (same result can be achieved with slicing or spilt):
old_dict = {
'1': 'robert; james; pasta',
'2': 'peas; cupcake; happy times; peas'
}
new_dict = {}
for key in old_dict:
old_dict[key] = old_dict[key].partition(';')[0]
resulting in:
{'1': 'robert', '2': 'peas'}

Python dict value query without iterating [duplicate]

I have the following dictionary in python:
d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
I need a way to find if a value such as "one" or "two" exists in this dictionary.
For example, if I wanted to know if the index "1" existed I would simply have to type:
"1" in d
And then python would tell me if that is true or false, however I need to do that same exact thing except to find if a value exists.
>>> d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
>>> 'one' in d.values()
True
Out of curiosity, some comparative timing:
>>> T(lambda : 'one' in d.itervalues()).repeat()
[0.28107285499572754, 0.29107213020324707, 0.27941107749938965]
>>> T(lambda : 'one' in d.values()).repeat()
[0.38303399085998535, 0.37257885932922363, 0.37096405029296875]
>>> T(lambda : 'one' in d.viewvalues()).repeat()
[0.32004380226135254, 0.31716084480285645, 0.3171098232269287]
EDIT: And in case you wonder why... the reason is that each of the above returns a different type of object, which may or may not be well suited for lookup operations:
>>> type(d.viewvalues())
<type 'dict_values'>
>>> type(d.values())
<type 'list'>
>>> type(d.itervalues())
<type 'dictionary-valueiterator'>
EDIT2: As per request in comments...
>>> T(lambda : 'four' in d.itervalues()).repeat()
[0.41178202629089355, 0.3959040641784668, 0.3970959186553955]
>>> T(lambda : 'four' in d.values()).repeat()
[0.4631338119506836, 0.43541407585144043, 0.4359898567199707]
>>> T(lambda : 'four' in d.viewvalues()).repeat()
[0.43414998054504395, 0.4213531017303467, 0.41684913635253906]
In Python 3, you can use
"one" in d.values()
to test if "one" is among the values of your dictionary.
In Python 2, it's more efficient to use
"one" in d.itervalues()
instead.
Note that this triggers a linear scan through the values of the dictionary, short-circuiting as soon as it is found, so this is a lot less efficient than checking whether a key is present.
Python dictionary has get(key) function
>>> d.get(key)
For Example,
>>> d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
>>> d.get('3')
'three'
>>> d.get('10')
None
If your key does not exist, then it will return None value.
foo = d[key] # raise error if key doesn't exist
foo = d.get(key) # return None if key doesn't exist
Content relevant to versions less than 3.0 and greater than 5.0.
Use dictionary views:
if x in d.viewvalues():
dosomething()..
Different types to check the values exists
d = {"key1":"value1", "key2":"value2"}
"value10" in d.values()
>> False
What if list of values
test = {'key1': ['value4', 'value5', 'value6'], 'key2': ['value9'], 'key3': ['value6']}
"value4" in [x for v in test.values() for x in v]
>>True
What if list of values with string values
test = {'key1': ['value4', 'value5', 'value6'], 'key2': ['value9'], 'key3': ['value6'], 'key5':'value10'}
values = test.values()
"value10" in [x for v in test.values() for x in v] or 'value10' in values
>>True
You can use this:
d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
print("one" in d.values)
Or you can use any function:
print(any([True for i,j in d1.items() if j == "one"]))
In Python 3 you can use the values() function of the dictionary. It returns a view object of the values. This, in turn, can be passed to the iter function which returns an iterator object. The iterator can be checked using in, like this,
'one' in iter(d.values())
Or you can use the view object directly since it is similar to a list
'one' in d.values()

Python (3.4) Recursion function not being called on dict/tree flattening [duplicate]

This question already has answers here:
Python: using a recursive algorithm as a generator
(3 answers)
Closed 7 years ago.
I'm trying to flatten a nested dictionary while also swapping out its keys according to another nested dict. I assume that none of the branches will have identical keys. E.g.:
In:
values_dict_test = {"abs": 3, "cd": 23, "sdf": "abc", "gxr":
{"rea": 21, "bdf": 95}}
mapping_dict_test = {"abs": "one", "cd": "two", "sdf": "three", "gxr":
{"rea": "four", "bdf": "five"}}
Expected Out:
{"one": 3, "two": 23, "three": "abc", "four": 21, "five": 95}
I'm using the iteritems hack to try to make this code compatible with Python 2.7, but am testing on 3.4. I've added a bunch of print statements to trace execution; it appears the recursive call never actually happens.
try:
dict.iteritems
except AttributeError:
# Python 3
def itervalues(d):
return iter(d.values())
def iteritems(d):
return iter(d.items())
else:
# Python 2
def itervalues(d):
return d.itervalues()
def iteritems(d):
return d.iteritems()
def flatten_dict(mapping, values_dict):
print("Function called with {} and {}".format(mapping, values_dict))
for (key, value) in iteritems(mapping):
print("K: {} V: {} Mapping: {}".format(key, value, mapping))
if isinstance(value, dict):
# Note that we have to flatten the values_dict as we flatten
# mapping dict, hence the [key]
print("Going to recurse")
print("Passing {} and {}".format(value, values_dict[key]))
flatten_dict(value, values_dict[key])
else:
print("Going to yield {}, {}".format(value, values_dict[key]))
yield (value, values_dict[key])
values_dict_test = {"abs": 3, "cd": 23, "sdf": "abc", "gxr":
{"rea": 21, "bdf": 95}}
mapping_dict_test = {"abs": "one", "cd": "two", "sdf": "three", "gxr":
{"rea": "four", "bdf": "five"}}
for (x,y) in flatten_dict(mapping_dict_test, values_dict_test):
print(x, y)
OUTPUT:
Function called with {'cd': 'two', 'sdf': 'three', 'abs': 'one', 'gxr': {'rea': 'four', 'bdf': 'five'}} and {'cd': 23, 'sdf': 'abc', 'abs': 3, 'gxr': {'rea': 21, 'bdf': 95}}
K: cd V: two Mapping: {'cd': 'two', 'sdf': 'three', 'abs': 'one', 'gxr': {'rea': 'four', 'bdf': 'five'}}
Going to yield two, 23
two 23
K: sdf V: three Mapping: {'cd': 'two', 'sdf': 'three', 'abs': 'one', 'gxr': {'rea': 'four', 'bdf': 'five'}}
Going to yield three, abc
three abc
K: abs V: one Mapping: {'cd': 'two', 'sdf': 'three', 'abs': 'one', 'gxr': {'rea': 'four', 'bdf': 'five'}}
Going to yield one, 3
one 3
K: gxr V: {'rea': 'four', 'bdf': 'five'} Mapping: {'cd': 'two', 'sdf': 'three', 'abs': 'one', 'gxr': {'rea': 'four', 'bdf': 'five'}}
Going to recurse
Passing {'rea': 'four', 'bdf': 'five'} and {'rea': 21, 'bdf': 95}
(Normally, I'd use values = {key: value for (key, value) in values_dict_gen} where values_dict_gen is the generator returned by that function.)
EDIT: In favor of reopening, (1) the duplicate linked to uses a mutable default argument, which is known to behave counter-intuitively in these situations (2) it's older, and the answer given below shows a Python 3.3 solution I didn't see on the older question.
flatten_dict(value, values_dict[key])
This call does the same thing inside a generator as it would outside; it creates a generator object. It does not automatically run the generator and yield its items. If you want to use a generator recursively, you have to iterate over it yourself:
for item in flatten_dict(value, values_dict[key]):
yield item
or in Python 3:
yield from flatten_dict(value, values_dict[key])

Categories