Python Dictionary: Serialized Strings - python-2.7

enter image description here
I have defined a python dictionary named "values" as shown above and it has several rows. I am trying to access the key:value pair for each row one by one if the key named "Risk: is high. I tried something like :
for i in range(len(rows)-1):
a = []
if values["Risk"][i]=='high':
a.append(values[key][i])
But the problem is it just appends the first character of each value. So instead of getting the vale 'Male' against the key 'Gender', I got 'M'. I am new to python and don't really understand the issue here.
Any suggestions?
Thanks!!

I know that this isn't a direct answer to your question, but I think you are having difficulties because of the way you are storing the "loaner" information. If you switched to a class-based model everything would get easier, more intuitive, and less hard-coded:
class LoanInfo(object):
__slots__ = ["HairLength","Employed","Age","Student",
"PreviouslyDeclined","Risk","FirstLoan","Gender",
"TypeOfColateral","LifeInsurance"]
def __init__(self,HairLength,Employed,Age,Student,PreviouslyDeclined,Risk,FirstLoan,Gender,TypeOfColateral,LifeInsurance):
self.HairLength = HairLength
self.Employed = Employed
self.Age = Age
self.Student = Student
self.PreviouslyDeclined = PreviouslyDeclined
self.Risk = Risk
self.FirstLoan = FirstLoan
self.Gender = Gender
self.TypeOfColateral = TypeOfColateral
self.LifeInsurance = LifeInsurance
loan_info_1 = LoanInfo('Short', 'Yes', 'Young', 'No', 'No', 'high', 'No', 'Male', 'Car', 'Yes')
loan_info_2 = LoanInfo('Short', 'Yes', 'Young', 'No', 'No', 'high', 'Yes', 'Male', 'Car', 'No')
loaners = [loan_info_1, loan_info_2]
rows = loan_info_1.__slots__ #<-- the slots of the object are the rows you want
high_risk_genders = []
for loaner in loaners:
if loaner.Risk == 'high':
high_risk_genders.append(loaner.Gender)
print high_risk_genders
output:
['Male', 'Male']
This is a more pythonic way of handling your problem. There is a lot of help online for python classes such as http://www.tutorialspoint.com/python/python_classes_objects.htm

After spending a while, you should think how to get data from a source you're using, because they're inadequate to calculate on them. I wish to help you, but I think that if I'll know the source from you get items from both dict and rows I will solve this issue totally different. If you want to solve this issue and it's really valuable for you, then just add more data to your question. That's all I can write.

Related

How do I make row-based tuples from column range or list?

This is probably really simple but I'm not too clear.
Let's say I have a data frame and a list of column references. My goal is to make a list of tuples that give that row number's values for only the columns contained in my list.
raw_data = {'first_name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'],
'last_name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze'],
'sex': ['male', 'female', 'male', 'female', 'female'],
'dog': ['Burt','Kane','Billy','Bob','Thorton'],
'cat': ['Evil','PurrEvil','Rorry','Meowth','Killer'],
'fish': ['Johhny','Nemo','Dorry','Jacob','Pinky']}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'sex'])
colref = ['dog','cat','fish']
I want to make a list of tuples like [['Burt','Evil','Johhny'],['Kane','PurrEvil','Nemo'],...]
but I want to do so without hardcoding column names or numbers. The real data set I am performing this on is much larger and variable in size but my list colref will always include all of the columns I want in my tuple list. Does anyone have any tips for me?
I think I may have figured it out.. lol
tuples = [tuple(x) for x in df[colref].values]
If there is a better solution though please let me know. I'm having fun looking at other people's solutions to the problems I encounter as a noob.

Python - can i recall a list name from raw_input?

I'm trying to create a game using python, but in my 'class Character:', i would like to do something like:
answer = raw_input('Which class do you want to play')
if answer = list_name[0]
self.stats = list_name
Thank you!
First note that your if statement should have an == instead of =
Also this type of situation is a great time to use python's in statement which will check if a value matches any of the items in your list! You could try something like this:
list_name = ['classA','classB','classC','classD']
answer = raw_input('Which class do you want to play: ')
#Check if the answer is one of the options in your list
if answer in list_name:
my_stats = answer
print 'great, your class is '+my_stats
else:
print 'sorry, ['+answer+'] is not an ok class'

python - good way to compare 2 dictionaries with nested values of different types?

I'm new to python and have written some code that does this comparison, but it's really inefficient and like 150 lines long.
Here are 2 example dicts to compare (in reality they are much longer, but are not much deeper than this, and only these data types).
dict1 = {
'id': '1',
'file': 'filename1',
'namespace1': {'key1': 'val1',
'key2': 'val2',
'key3': 'val3'},
'namespace2': {'key4': ['listval1', 'listval2', 'listval3'],
'key5': 'val5'}
}
dict2 = {
'id': '2',
'file': 'filename2',
'namespace1': {'key1': 'val1',
'key2': 'val2',
'key3': 'val7'},
'namespace2': {'key4': ['listval1', 'listval2', 'listval7'],
'key5': 'val5'},
'namespace3': 'key6'
}
Is there any efficient way to compare these two dictionaries and store the differences to display? I'm having a really hard time with this... I'm thinking the correct way is to convert to sets and recursively compare, but I'm not sure it's going to work properly. Any help is much appreciated. Thanks!
I think you need to be more accurate by "compare" definition.
Maybe try to use deepdiff package using:
pip install deepdiff
Use as follow:
from deepdiff import DeepDiff
print DeepDiff(dict1, dict2)
It show exactly what are the changes between those two dicts

counting occurrence of name in list of namedtuple (the name is in a nested tuple)

As the title says, i'm trying to count the occurrence of a name in a list of namedtuples, with the name i'm looking for in a nested tuple.
It is an assignment for school, and a big part of the code is given.
The structure of the list is as follows:
paper = namedtuple( 'paper', ['title', 'authors', 'year', 'doi'] )
for (id, paper_info) in Summaries.iteritems():
Summaries[id] = paper( *paper_info )
It was easy to get the number of unique titles for each year, since both 'title' and 'year' contain one value, but i can't figure out how to count the number of unique authors per year.
I don't expect you guys to give me the entire code or something, but if you could give me a link to a good tutorial about this subject this would help a lot.
I did google around a lot, but i cant find any helpful information!
I hope i'm not asking too much, first time i ask a question here.
EDIT:
Thanks for the responses so far. This is the code i have now:
authors = [
auth
for paper in Summaries.itervalues()
for auth in paper.authors
]
authors
The problem is, i only get a list of all the authors with this code. I want them linked to the year tough, so i can check the amount of unique authors for each year.
For keeping track of unique objects, I like using set. A set behaves like a mathematical set in that it can have at most one copy of any given thing in it.
from collections import namedtuple
# by convention, instances of `namedtuple` should be in UpperCamelCase
Paper = namedtuple('paper', ['title', 'authors', 'year', 'doi'])
papers = [
Paper('On Unicorns', ['J. Atwood', 'J. Spolsky'], 2008, 'foo'),
Paper('Discourse', ['J. Atwood', 'R. Ward', 'S. Saffron'], 2012, 'bar'),
Paper('Joel On Software', ['J. Spolsky'], 2000, 'baz')
]
authors = set()
for paper in papers:
authors.update(paper.authors) # "authors = union(authors, paper.authors)"
print(authors)
print(len(authors))
Output:
{'J. Spolsky', 'R. Ward', 'J. Atwood', 'S. Saffron'}
4
More compactly (but also perhaps less readably), you could construct the authors set by doing:
authors = set([author for paper in papers for author in paper.authors])
This may be faster if you have a large volume of data (I haven't checked), since it requires fewer update operations on the set.
If you don't want to use embeded type set() and want to understand the logic, use a list and if bifurcation.
If we don't use set() in senshin's code:
# authors = set()
# for paper in papers:
# authors.update(paper.authors) # "authors = union(authors, paper.authors)"
authors = []
for paper in papers:
for author in paper.authors:
if not author in authors:
authors.append(author)
You can get similar result as senshin's. I hope it helps.

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])