Find the minimum and display the variable name in python - python

You have got three variables like
a = 1
b = 2
c = 3
and you find the minimum can you somehow display the variable name instead of the value it has
Example
d = min[a,b,c]
after this operation d should become c since c is the greatest. Or maybe there's some alternative way because i want to assign the variable name in another operation afterwards.

Put variables into a dictionary and call min() with specifying dictionary get as a key:
>>> a = 1
>>> b = 2
>>> c = 3
>>> data = {'a': a, 'b': b, 'c': c}
>>> min(data, key=data.get)
'a'

You shouldn't do that. Instead, you should do something like:
data = {
'a' : 1
'b' : 2
'c' : 3
}
# get the minimum item, by the value.
smallest = min(data.items(), key = lambda item: item[1])
data[smallest] = my_new_value

Related

Bast way to update a value in a dict

I have a dict that contains parameters. I want to consider that any unspecified parameter should be read as a zero. I see several ways of doing it and wonder which one is recommended:
parameters = {
"apples": 2
}
def gain_fruits0 (quantity, fruit):
if not fruit in parameters :
parameters[fruit] = 0
parameters[fruit] += quantity
def gain_fruits1 (quantity, fruits):
parameters[fruit] = quantity + parameters.get(fruit,0)
parameters is actually way bigger than that, if that is important to know for optimization purposes.
So, what would be the best way? gain_fruits0, gain_fruits1, or something else?
This is a typical use of defaultdict, which works exactly like a regular dictionary except that it has the functionality you're after built in:
>>> from collections import defaultdict
>>> d = defaultdict(int) # specify default value `int()`, which is 0
>>> d['apples'] += 1
>>> d
defaultdict(int, {'apples': 1})
>>> d['apples'] # can index normally
1
>>> d['oranges'] # missing keys map to the default value
0
>>> dict(d) # can also cast to regular dict
{'apples': 1, 'oranges': 0}

Combine pop() and setdefault() in python

I'm trying to build a method where if an item is not in a dictionary then it uses the last member of a list and updates the dictionary accordingly. Sort of like a combination of the pop and setdefault method. What I tried was the following:
dict1 = {1:2,3:4,5:6}
b = 7
c = [8,9,10]
e = dict1.setdefault(b, {}).update(pop(c))
So I would like the output to be where {7:10} gets updated to dict1, that is to say, if b is not in the keys of dict1 then the code updates dict1 with an item using b and the last item of c.
It might be possible for you to abuse a defaultdict:
from collections import defaultdict
c = [8, 9, 10]
dict1 = defaultdict(c.pop, {1: 2, 3: 4, 5: 6})
b = 7
e = dict1[b]
This will pop an item from c and make it a value of dict1 whenever a key missing from dict1 is accessed. (That means the expression dict1[b] on its own has side-effects.) There are many situations where that behaviour is more confusing than helpful, though, in which case you can opt for explicitness:
if b in dict1:
e = dict1[b]
else:
e = dict1[b] = c.pop()
which can of course be wrapped up in a function:
def get_or_pop(mapping, key, source):
if key in mapping:
v = mapping[key]
else:
v = mapping[key] = source.pop()
return v
⋮
e = get_or_pop(dict1, b, c)
Considering your variables, you could use the following code snippet
dict1[b] = dict1.pop(b, c.pop())
where you are updating the dictionary "dict1" with the key "b" and the value c.pop(), (last value of the list in c, equivalent to c[-1] in this case). Note that this is possible because the key value b=7 is not in you original dictionary.

How is this Python 2.7 setdefault/ defaultdict code giving a nested result?

This seems to be a pretty straightforward use of setdefault and defaultdict which I am not able to understand, it would be great if someone could explain "why" the code below works.
d = {}
for name in ['foo', 'bar', 'bars']:
t = d
for char in name:
t = t.setdefault(char,{}) # Should be a empty {}
print d
# Prints {'b': {'a': {'r': {'s': {}}}}, 'f': {'o': {'o': {}}}}
I am not able to understand how this piece of code works. When the line t = t.setdefault(char,{}) executes it should assign a empty dictionary to t, but how is it affecting d such that d ends up becoming a nested dictionary?
Also, what would be the equivalent of the above if I were to use defaultdict. I came up with this which is wrong:
d1 = defaultdict(dict)
for name in ['foo', 'bar', 'bars']:
t1 = d1
for char in name:
t1 = t1[char]
print d1
It would be great if someone could point out as to how one should understand defaultdicts
I'll walk through the loop one step at a time, and explain how it proceeds to assign the nested dicts:
name = 'foo'
t = d # both t and d point to the same empty dict object
char = 'f'
t = t.setdefault(char,{})
# the first thing evaluated is the right hand side:
# now d['f'] = {}, since that key wasn't in the dict
# t points to the same object here
# now the result of the left side (a new empty dict) is assigned to `t`.
# this empty dict is also the exact *same* object referenced by d['f'] as well though!
# so at this point d['f'] = {}, and t = {}, and both those dicts are the same!
char = 'o'
t = t.setdefault(char,{})
# eval the right side again, so now t['o'] = {}, but remember d['f'] == t
# so really d['f'] = {'o':{}}
# and again we assign the result of the right side to a brand new `t`
# so now d['f']['o'] = {}, and t['o'] = {}, and these empty dicts are
# again referencing the same object
char = 'o'
t = t.setdefault(char,{})
# our `t` from last time is empty, so it gets assigned the same as before
# and now d['f']['o']['o'] = {}
name = 'bar'
t = d # re-start this, but with d['f']['o']['o'] = {}
char = 'b'
#...everything proceeds as before - since 'b' is not in `d`,
# we start generating nested dicts again
# ...
...
name = 'bars'
# main difference here is that d['b']['a']['r'] exists,
# so we end up just adding the 's':{} to the end
As for the defaultdict equivalent, that is a little trickier.
The issue is you need defaultdict's all-the-way-down
I found a way to do that with a little function here
from collections import defaultdict
def fix(f):
return lambda *args, **kwargs: f(fix(f), *args, **kwargs)
d1 = fix(defaultdict)()
for name in ['foo', 'bar', 'bars']:
t1 = d1
for char in name:
t1 = t1[char]
print d1
For the first part, the line t = d does not make a copy of d. It only creates a new reference to d and stores it in t. t and d now refer to the same object; in other words, you have only one object, but two names for that object. Since that object is a mutable object (a dict, in this case), changing t also changes d since there is only one object. While that's necessary here, if for some reason in other code you want to make a copy of a mutable object and operate on the copy without modifying the original, you need to import copy and use copy.deepcopy().
On the second, the defaultdict() constructor expects, as its first argument, a callable that accepts no arguments and returns the default value. However, for this case, that return value would need to be another defaultdict with a callable returning another defaultdict with a callable returning yet another... etc. It's infinite recursion.
So there is no defaultdict equivalent to this code. Instead, the original version with setdefault and plain dicts is probably the best and most Pythonic way to do it.
how setdefault works in dictionary
# case 1
d = {}
temp = d.setdefault("A")
print "d = ", d
print "temp = ", temp
print "id of d = ", id(d), "id of temp = ", id(temp)
# output
d = {'A': None}
temp = None
id of d = 140584110017624, id of temp = 9545840 # memory locations of d, temp
# case 2
d = {}
temp = d.setdefault("A", "default Value")
print "d = ", d
print "temp = ", temp
print "id of d = ", id(d), "id of temp = ", id(temp)
# output
d = {'A': "default Value"}
temp = "default Value"
id of d = 140584110017624, id of temp = 9545840 # memory locations of d, temp
I your code t=d means memory location of t and d both are same.
so, when the code t = t.setdefault(char,{}) excecutes first t.setdefault(char,{}) executes and changes the content in memory location of t, then it returns the content then it assigns the new memory location to name t and assigns the returned value to it.
memory location of t and d are same that's the reason d is getting affected.

Is it possible to "unpack" a dict in one call?

I was looking for a way to "unpack" a dictionary in a generic way and found a relevant question (and answers) which explained various techniques (TL;DR: it is not too elegant).
That question, however, addresses the case where the keys of the dict are not known, the OP anted to have them added to the local namespace automatically.
My problem is possibly simpler: I get a dict from a function and would like to dissecate it on the fly, knowing the keys I will need (I may not need all of them every time). Right now I can only do
def myfunc():
return {'a': 1, 'b': 2, 'c': 3}
x = myfunc()
a = x['a']
my_b_so_that_the_name_differs_from_the_key = x['b']
# I do not need c this time
while I was looking for the equivalent of
def myotherfunc():
return 1, 2
a, b = myotherfunc()
but for a dict (which is what is returned by my function). I do not want to use the latter solution for several reasons, one of them being that it is not obvious which variable corresponds to which returned element (the first solution has at least the merit of being readable).
Is such operation available?
If you really must, you can use an operator.itemgetter() object to extract values for multiple keys as a tuple:
from operator import itemgetter
a, b = itemgetter('a', 'b')(myfunc())
This is still not pretty; I'd prefer the explicit and readable separate lines where you first assign the return value, then extract those values.
Demo:
>>> from operator import itemgetter
>>> def myfunc():
... return {'a': 1, 'b': 2, 'c': 3}
...
>>> itemgetter('a', 'b')(myfunc())
(1, 2)
>>> a, b = itemgetter('a', 'b')(myfunc())
>>> a
1
>>> b
2
You could also use map:
def myfunc():
return {'a': 1, 'b': 2, 'c': 3}
a,b = map(myfunc().get,["a","b"])
print(a,b)
In addition to the operator.itemgetter() method, you can also write your own myotherfunc(). It takes list of the required keys as an argument and returns a tuple of their corresponding value.
def myotherfunc(keys_list):
reference_dict = myfunc()
return tuple(reference_dict[key] for key in keys_list)
>>> a,b = myotherfunc(['a','b'])
>>> a
1
>>> b
2
>>> a,c = myotherfunc(['a','c'])
>>> a
1
>>> c
3

How to iterate over the elements of a map in python

Given a string s, I want to know how many times each character at the string occurs. Here is the code:
def main() :
while True :
try :
line=raw_input('Enter a string: ')
except EOFError :
break;
mp={};
for i in range(len(line)) :
if line[i] in mp :
mp[line[i]] += 1;
else :
mp[line[i]] = 1;
for i in range(len(line)) :
print line[i],': ',mp[line[i]];
if __name__ == '__main__' :
main();
When I run this code and I enter abbba, I get:
a : 2
b : 3
b : 3
b : 3
a : 2
I would like to get only:
a : 2
b : 3
I understand why this is happening, but as I'm new to python, I don't know any other ways to iterate over the elements of a map. Could anyone tell me how to do this? Thanks in advance.
You could try a Counter (Python 2.7 and above; see below for a pre-2.7 option):
>>> from collections import Counter
>>> Counter('abbba')
Counter({'b': 3, 'a': 2})
You can then access the elements just like a dictionary:
>>> counts = Counter('abbba')
>>> counts['a']
2
>>> counts['b']
3
And to iterate, you can use #BurhanKhalid's suggestion (the Counter behaves as a dictionary, where you can iterate over the key/value pairs):
>>> for k, v in Counter('abbba').iteritems():
... print k, v
...
a 2
b 3
If you're using a pre-2.7 version of Python, you can use a defaultdict to simplify your code a bit (process is still the same - only difference is that now you don't have to check for the key first - it will 'default' to 0 if a matching key isn't found). Counter has other features built into it, but if you simply want counts (and don't care about most_common, or being able to subtract, for instance), this should be fine and can be treated just as any other dictionary:
>>> from collections import defaultdict
>>> counts = defaultdict(int)
>>> for c in 'abbba':
... counts[c] += 1
...
>>> counts
defaultdict(<type 'int'>, {'a': 2, 'b': 3})
When you use iteritems() on a dictionary (or the Counter/defaultdict here), a key and a value are returned for each iteration (in this case, the key being the letter and the value being the number of occurrences). One thing to note about using dictionaries is that they are inherently unordered, so you won't necessarily get 'a', 'b', ... while iterating. One basic way to iterate through a dictionary in a sorted manner would be to iterate through a sorted list of the keys (here alphabetical, but sorted can be manipulated to handle a variety of options), and return the dictionary value for that key (there are other ways, but this will hopefully be somewhat informative):
>>> mapping = {'some': 2, 'example': 3, 'words': 5}
>>> mapping
{'some': 2, 'example': 3, 'words': 5}
>>> for key in sorted(mapping.keys()):
... print key, mapping[key]
...
example 3
some 2
words 5
Iterating over a mapping yields keys.
>>> d = {'foo': 42, 'bar': 'quux'}
>>> for k in d:
... print k, d[k]
...
foo 42
bar quux
You need to look up the help for dict(). It's all there -- 'for k in mp' iterates over keys, 'for v in mp.values()' iterates over values, 'for k,v in mp.items()' iterates over key, value pairs.
Also, you don't need those semicolons. While they are legal in Python, nobody uses them, there's pretty much no reason to.
Python 2.5 and above
dDIct = collections.defaultdict(int)
[(d[i]+=1) for i in line]
print dDict

Categories

Resources