Using integer as dictionary key using dict() - python-2.7

I'm trying to use numbers as my dict key. Is there anyway to initiate the dictionary using dict() method?
This works
mydict = { '100':'hundred', '200':'two hundred'}
This doesn't work?
mydict = dict( 100='hundred' )
The error says 'keyword can't be an expression' and I couldn't find any solution.
Thank you.

I can't understand your question exactly, but you mentioned to use number as dict key right? you just directly initiate it using integer instead string like this..
a = {1:'one',100:'hundered'}
print a
{1: 'one', 100: 'hundrered'}

No, it mist be a valid python identifier, so it cannot start with a number.
You can read where i found it at here in the part about dict
https://docs.python.org/2/library/stdtypes.html#typesmapping
Like the comment above says you can use an int, since dictionaries just hash the string and you get an int anyways, in the case of an int it just hashes to itself. But it doesnt work with dict ()
On that page it shows you can do
mydict = dict (zip ([1], ["one"]))
Which is kinda ugly imo, but seems to get the job done

To use the dict method you need to feed it a list or tuple of lists or tuples.
>>> dict([(100, 'hundred'), (200, 'two hundred')])
{200: 'two hundred', 100: 'hundred'}

Related

How to iterate and store variables in a dictionary?

I am new to python and my coding experience so far is with MATLAB.
I am trying to understand more about lists and dictionaries as i am using a library about DOEs that takes an dictionary as a passing argument.
But my trouble so far is that this dictionary assumes the form of ex.
DOE={'Elastic Modulus':[10,20,30], 'Density':[1,2,3], 'Thickness':[2,3,5]}
But i need this dictionary to be user defined, for example:
Have an input to define how many variables are needed (in this example are 3: Elastic Modulus','Density'and 'Thickness)
as the variables are defined, it should be able to store values in the dictionary over a for loop.
Is this possible using dictionaries?
Or is it better to use a list and convert in a dicionary later?
Thank you in advance
One can add keys and the corresponding values to a dict one at a time like so:
my_dict = {}
num_entries = int(input("How many entries "))
for _ in range(num_entries):
key = input("Enter the key: ")
value = input("Enter the value: ")
my_dict[key] = value
Presumably you would have a loop to do the entry of key and value for the number of values you wish to enter. Also if you are in python 2 it needs to be raw_input rather than input function. [Edit: Showing how to do the loop, since I noticed that was part of your question]

Sort nested dictionary in ascending order and grab outer key?

I have a dictionary that looks like:
dictionary = {'article1.txt': {'harry': 3, 'hermione': 2, 'ron': 1},
'article2.txt': {'dumbledore': 1, 'hermione': 3},
'article3.txt': {'harry': 5}}
And I'm interested in picking the article with the most number of occurences of Hermione. I already have code that selects the outer keys (article1.txt, article2.txt) and inner key hermione.
Now I want to be able to have code that sorts the dictionary into a list of ascending order for the highest number occurrences of the word hermione. In this case, I want a list such that ['article1.txt', 'article2.txt']. I tried it with the following code:
#these keys are generated from another part of the program
keys1 = ['article1.txt', 'article2.txt']
keys2 = ['hermione', 'hermione']
place = 0
for i in range(len(keys1)-1):
for j in range(len(keys2)-1):
if articles[keys1[i]][keys2[j]] > articles[keys1[i+1]][keys2[j+1]]:
ordered_articles.append(keys1[i])
place += 1
else:
ordered_articles.append(place, keys1[i])
But obviously (I'm realizing now) it doesn't make sense to iterate through the keys to check if dictionary[key] > dictionary[next_key]. This is because we would never be able to compare things not in sequence, like dictionary[key[1]] > dictionary[key[3]].
Help would be much appreciated!
It seems that what you're trying to do is sort the articles by the amount of 'hermiones' in them. And, python has a built-in function that does exactly that (you can check it here). You can use it to sort the dictionary keys by the amount of hermiones each of them points to.
Here's a code you can use as example:
# filters out articles without hermione from the dictionary
# value here is the inner dict (for example: {'harry': 5})
dictionary = {key: value for key, value in dictionary.items() if 'hermione' in value}
# this function just returns the amount of hermiones in an article
# it will be used for sorting
def hermione_count(key):
return dictionary[key]['hermione']
# dictionary.keys() is a list of the keys of the dictionary (the articles)
# key=... here means we use hermione_count as the function to sort the list
article_list = sorted(dictionary.keys(), key=hermione_count)

Reversing str.format() - getting arguments by placeholder

What is the most elegant way to reverse the process of Python's str.format on replacing arguments by position?
For example for the following
textpattern = 'Please move {0} to {1}'
mystring = 'Please move a to b'
a deformat function :
mystring.deformat(textpattern)
will return the list ['a', 'b']. The variable textpattern is being entered by the user and then dynamically fetched from the DB.
The closest thing I found is a question about scnaf in Python but that's slightly different.
You're looking for the package parse which is described as: parse() is the opposite of format().

compare two dictionary and display the image based on the key in python

How can i compare two dictionary and based on the matching keys I have to display the images. I mean if the key matched with the first dictionary and its in the second too, then i have to take the image based on the key. I have given a try, and the code is:
for key in res_lst_srt:
if key in resizedlist:
b,g,r = cv2.split(images[i])
img = cv2.merge((r,g,b))
plt.subplot(2,3,i+1),plt.imshow(img)
plt.xticks([]),plt.yticks([])
plt.show()
I have taken the query image seperately, and i have got the distance between the query image,and all the database image. Distance have key and value, database image have key and value. I want to retrieve the image which matches the best with minimum distance based on key.
Thanks in advance!
It seems to me that you are not properly into the dict concept, you should study it a little bit to understand how it works with simple elements (number, strings) and only when you got it try with the heavy datas as opencv images.
Try this piece of code:
dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'e':1, 'd':2, 'c':4}
print dict1
print dict2
# note that this code is not optimized!!
# there are plenty of ways you can do better
# but prob. is the easiest way == better way to understand it
for k1 in dict1.keys():
for k2 in dict2.keys():
if k1==k2:
print 'keys matches'
mergedvalues = dict1[k1] + dict2[k2]
print 'merged value is:', merged values
for better ways to compare two dicts going deep in python way of handling dict and other data structures (as list, set, etc) and operations on that, this answer is nice. but I think you should understand how dict works before.

Is there any way to do a case-insensitive IN query in Django?

Nearly every kind of lookup in Django has a case-insensitive version, EXCEPT in, it appears.
This is a problem because sometimes I need to do a lookup where I am certain the case will be incorrect.
Products.objects.filter(code__in=[user_entered_data_as_list])
Is there anything I can do to deal with this? Have people come up with a hack to work around this issue?
I worked around this by making the MySQL database itself case-insensitive. I doubt that the people at Django are interested in adding this as a feature or in providing docs on how to provide your own field lookup (assuming that is even possible without providing code for each db backend)
Here is one way to do it, admittedly it is clunky.
products = Product.objects.filter(**normal_filters_here)
results = Product.objects.none()
for d in user_entered_data_as_list:
results |= products.filter(code__iexact=d)
If your database is MySQL, Django treats IN queries case insensitively. Though I am not sure about others
Edit 1:
model_name.objects.filter(location__city__name__in': ['Tokio','Paris',])
will give following result in which city name is
Tokio or TOKIO or tokio or Paris or PARIS or paris
If it won't create conflicts, a possible workaround may be transforming the strings to upper or lowercase both when the object is saved and in the filter.
Here is a solution that do not require case-prepared DB values.
Also it makes a filtering on DB-engine side, meaning much more performance than iterating over objects.all().
def case_insensitive_in_filter(fieldname, iterable):
"""returns Q(fieldname__in=iterable) but case insensitive"""
q_list = map(lambda n: Q(**{fieldname+'__iexact': n}), iterable)
return reduce(lambda a, b: a | b, q_list)
The other efficient solution is to use extra with quite portable raw-SQL lower() function:
MyModel.objects.extra(
select={'lower_' + fieldname: 'lower(' + fieldname + ')'}
).filter('lover_' + fieldname + '__in'=[x.lower() for x in iterable])
Another solution - albeit crude - is to include the different cases of the original strings in the list argument to the 'in' filter. For example: instead of ['a', 'b', 'c'], use ['a', 'b', 'c', 'A', 'B', 'C'] instead.
Here's a function that builds such a list from a list of strings:
def build_list_for_case_insensitive_query(the_strings):
results = list()
for the_string in the_strings:
results.append(the_string)
if the_string.upper() not in results:
results.append(the_string.upper())
if the_string.lower() not in results:
results.append(the_string.lower())
return results
A lookup using Q object can be built to hit the database only once:
from django.db.models import Q
user_inputed_codes = ['eN', 'De', 'FR']
lookup = Q()
for code in user_inputed_codes:
lookup |= Q(code__iexact=code)
filtered_products = Products.objects.filter(lookup)
A litle more elegant way would be this:
[x for x in Products.objects.all() if x.code.upper() in [y.upper() for y in user_entered_data_as_list]]
You can do it annotating the lowered code and also lowering the entered data
from django.db.models.functions import Lower
Products.objects.annotate(lower_code=Lower('code')).filter(lower_code__in=[user_entered_data_as_list_lowered])