I have a dictionary (with multiple objects) I am trying to create a list that sums some of the values for each object. So far I have:
import csv,os,re
#numpy.corrcoef(list1, list2)[0, 1]
input_dict = csv.DictReader(open("./MCPlayerData/AllPlayerData2.csv"))
npi_scores=[]
for person in input_dict:
#print person
i=0
for key in person:
if re.match(r'npi[0-9]+', key):
#print key,'=',person[key] #returns npi0=1,npi1=3,npi3=2,etc
try:
i+=person[key]
#print(person[key])
except TypeError:
i="NA" #returns NA because one of the values wasnt filled out with an integer
break
npi_scores.append(i)
break
print npi_scores #returns sum of npi scores for one person
print('DONE')
When I run this code I get NA based on the first element. Which is what I would expect if the value wasnt an integer, but all are definitely integers. Any ideas?
convert person[key] to integer int(person[key]) ,or it will be treated as string
digit_str = person[key]
# checks value only consists of digits
if digit_str.isdigit():
# converts digits-only value to integer
i += int(digit_str)
Related
I'm trying to count the amount of times "a class" occurs within each "h2 class", so I split the parsed texted by "h2 class" but am having struggles with the second part, this is where I'm at
#splitting parsed text by header
parsed.split("h2 class")
#creating the list for the a value count to be stored
aValCount = []
#counting amount of items per header
for i in range (len(parsed)):
aValCount = aValCount + ((parsed[i]).count("a class"))
the error I'm getting is
TypeError: can only concatenate list (not "int") to list
, but I can't figure out how to this without getting some sort of error
Edited: Thought I should add, I want it to be a list of the counts from the strings, so the count from element one in parsed, should be element 1 in aValCount
The issue is that aValCount is an array and ((parsed[i]).count("a class")) is an int.
What you want is to add the count to aValCount so you need to pass another array.
aValCount = aValCount + [((parsed[i]).count("a class"))]
If you add [...] that should do it.
Or you can also do
aValCount.append(((parsed[i]).count("a class"))])
Hope that help.
results = parsed.split("h2 class")
aValCountList = []
for i in range (len(results)):
aValCountList.append((results[i]).count("a class"))
I have got a code and need to get the line by line meaning of this python code.
marksheet = []
for i in range(0,int(input())):
marksheet.append([raw_input(), float(input())])
second_highest = sorted(list(set([marks for name, marks in marksheet])))[1]
print('\n'.join([a for a,b in sorted(marksheet) if b == second_highest]))
I highly recommend you to go through the python tutorial
Just for your understanding of this code, I've added the comments.
#initialising an empty list!
marksheet = []
#iterating through a for loop starting from zero, to some user input(default type string) - that is converted to int
for i in range(0,int(input())):
#appending user input(some string) and another user input(a float value) as a list to marksheet
marksheet.append([raw_input(), float(input())])
#[marks for name, marks in marksheet] - get all marks from list
#set([marks for name, marks in marksheet]) - getting unique marks
#list(set([marks for name, marks in marksheet])) - converting it back to list
#sorting the result in decending order with reverse=True and getting the value as first index which would be the second largest.
second_highest = sorted(list(set([marks for name, marks in marksheet])),reverse=True)[1]
#printing the name and mark of student that has the second largest mark by iterating through the sorted list.
#If the condition matches, the result list is appended to tuple -`[a for a,b in sorted(marksheet) if b == second_highest])`
#now join the list with \n - newline to print name and mark of student with second largest mark
print('\n'.join([a for a,b in sorted(marksheet) if b == second_highest]))
Hope it helps!
Would do this in a comment but I don't have 50 reputation yet:
You don't need to use sorted on second_highest but apparently it is not a good habit to rely on this so you can keep the sorted. Calling sorted on an already sorted list doesn't use a lot of resources anyway.
second_highest = sorted(list(set([marks for name, marks in marksheet])))[1]
Also if the list contains something like [1,3,2,5,3,2,1] it will give 2 as result and not 1 since a set removes all duplicates.
If you want to keep duplicates use:
second_highest = sorted([marks for name, marks in marksheet]))[1]
I need to make a function that updates tuples in a list of tuples. The tuples contain transactions, which are characterised by ammount, day, and type. I made this function that should completely replace a tuple with a new one, but when I try to print the updated list of tuples I get the error:
TypeError: tuple indices must be integers or slices, not str
The code:
def addtransaction(transactions, ammount, day, type):
newtransactions = {
"Ammount": ammount,
"Day": day,
"Type": type
}
transactions.append(newtransaction)
def show_addtransaction(transactions):
Ammount = float(input("Ammount: "))
Day = input("Day: ")
Type = input("Type: ")
addtransaction(transactions, ammount, day, type)
def show_all_transaction(transactions):
print()
for i, transaction in enumerate(transactions):
print("{0}. Transaction with the ammount of {1} on day {2} of type: {3}".format(
i + 1,
transaction['Ammount'], ; Here is where the error occurs.
transaction['Day'],
transaction['Type']))
def update_transaction(transactions): ; "transactions" is the list of tuples
x = input("Pick a transaction by index:")
a = float(input("Choose a new ammount:"))
b = input("Choose a new day:")
c = input("Choose a new type:")
i = x
transactions[int(i)] = (a, b, c)
addtransaction(transactions, 1, 2, service)
show_all_transaction(transactions)
update_transaction(transactions)
show_all_transaction(transactions)
A tuple is basically only a list, with the difference that in a tuple you cannot overwrite a value in it without creating a new tuple.
This means you can only access each value by an index starting at 0, like transactions[0][0].
But as it appears you should actually use a dict in the first place. So you need to rewrite update_transaction to actually create a dict similar to how addtransaction works. But instead of adding the new transaction to the end you just need to overwrite the transaction at the given index.
This is what update_transaction already does, but it overwrites it with a tuple and not a dict. And when you print it out, it cannot handle that and causes this error.
Original answer (Before I knew the other functions)
If you want to use strings as indexes you need to use a dict. Alternatively you can use namedtuple which are like tuples but it also has an attribute for each value with the name you defined before. So in your case it would be something like:
from collections import namedtuple
Transaction = namedtuple("Transaction", "amount day type")
The names given by the string used to create Transaction and separated by spaces or commas (or both). You can create transactions by simply calling that new object. And accessing either by index or name.
new_transaction = Transaction(the_amount, the_day, the_type)
print(new_transaction[0])
print(new_transaction.amount)
Please note that doing new_transaction["amount"] will still not work.
This is not a generic answer, I'll just mention it if someone bumps into the same problem.
As stated before, tuples are addressed by integer e.g. my_tuple[int] or slice my_tuple[int1:int2].
I ran into trouble when I ported code from Python2 to Python3. The original code used somthing like my_tuple[int1/int2], this worked in Python2 since division int/int results in int.
in Python3 int/int results in a floating point number.
I had to fix the code to my_tuple[int1//int2] to get the python2 behavior.
I am trying to make a python program that takes user input text or a file and changes each character into a value and then returns the result.
I have a user string that being read into a list.
I am trying to have a for loop go through that list and check each character against a dictionary key and then return the value in the dictionary. How would i go about doing that?
Thanks
Code so far:
for i in range (0, len(text)):
for j in alphabet.keys():
if text[i].upper() == alphabet.values():
j+=1
print(alphabet.items())
i+=1
for item in list_:
try:
print(d[item])
except KeyError as e:
print("{} not in d".format(e.args[0]))
Without seeing your code, I can't offer anything more relevant
You probably want to use string.maketrans and string.translate
>>> import string
>>> table = string.maketrans('abc', 'xyz')
>>> string.translate('the cat is bad', table)
'the zxt is yxd'
Most of the code below is simply to create the dictionary that translates letters of an input into randomised corresponding values in a dict (i.e. each letter maps to another random letter). Points on your code:
1) range() automatically defaults to starting at 0 so range(0, n) is better just written as range(n)
2) You don't need to use range() at all here. for letter in string will take an input string and go through it, letter by letter. for elephant in string will do the same, each letter is being assigned to the name elephant in turn, so the fact that I chose to use letter instead is simply for readability.
3) Using keys(), values() and items() is not the way to query a dictionary. You have two standard approaches; I could use translation_dict[letter] which will throw KeyError if the value of letter is not a key in the dictionary, or translation_dict.get(letter) which will return None if the key doesn't exist. In the below example, I used get() but also added another parameter ("not in dict") which replaces None as the default value if the letter isn't found as a key.
import string # For setup of example data
import random # For setup of example data
# Just creating the translation dictionary and fake user input
alphabet = list(string.uppercase)
translated = random.sample(alphabet, len(alphabet))
translation_dict = {i: j for i, j in zip(alphabet, translated)}
user_input = 'Hello'
# The loop you're trying
for letter in user_input:
corresponding_value = translation_dict.get(letter.upper(), 'Not in dict')
print(corresponding_value)
I am trying to sort a file of sequences according to a certain parameter. The data looks as follows:
ID1 ID2 32
MVKVYAPASSANMSVGFDVLGAAVTP ...
ID1 ID2 18
MKLYNLKDHNEQVSFAQAVTQGLGKN ...
....
There are about 3000 sequences like this, i.e. the first line contains two ID field and one rank field (the sorting key) while the second one contains the sequence. My approach is to open the file, convert the file object to a list object, separate the annotation line (ID1, ID2, rank) from the actual sequence (annotation lines always occur on even indices, while sequence lines always occur on odd indices), merge them into a dictionary and sort the dictionary using the rank field. The code reads like so:
#!/usr/bin/python
with open("unsorted.out","rb") as f:
f = f.readlines()
assert type(f) == list, "ERROR: file object not converted to list"
annot=[]
seq=[]
for i in range(len(f)):
# IDs
if i%2 == 0:
annot.append(f[i])
# Sequences
elif i%2 != 0:
seq.append(f[i])
# Make dictionary
ids_seqs = {}
ids_seqs = dict(zip(annot,seq))
# Solub rankings are the third field of the annot list, i.e. annot[i].split()[2]
# Use this index notation to rank sequences according to solubility measurements
sorted_niwa = sorted(ids_seqs.items(), key = lambda val: val[0].split()[2], reverse=False)
# Save to file
with open("sorted.out","wb") as out:
out.write("".join("%s %s" % i for i in sorted_niwa))
The problem I have encountered is that when I open the sorted file to inspect manually, as I scroll down I notice that some sequences have been wrongly sorted. For example, I see the rank 9 placed after rank 89. Up until a certain point the sorting is correct, but I don't understand why it hasn't worked throughout.
Many thanks for any help!
Sounds like you're comparing strings instead of numbers. "9" > "89" because the character '9' comes lexicographically after the character '8'. Try converting to integers in your key.
sorted_niwa = sorted(ids_seqs.items(), key = lambda val: int(val[0].split()[2]), reverse=False)