Need Help to Realize a Function in a Python - python

I need to make a function that can check a given word and return another word. For example, if the input is "a1", the function will check for this word in the dictionary and return "a".
I know how to code it if it is just a single input word per category using a simple if-else, but I'm still confused if a category has more than 3 words. And I plan to have a lot of data in this dictionary. So a simple if-else would need a lot of code to be written.
this is the example for the input & output that i want:
Input : a2 Output : a
Input : b3 Output : b

If you really just need to strip a single digit number on the end (per your example):
words=['a1','a2','a3','a4','b1','b2','b3','c1','c2','d1']
realwords= set() # empty set, like a list, but can only have each item once, no duplication
for w in words:
realwords.add(w[:-1])
print(realwords)
{'c', 'a', 'b', 'd'}
If you have a more complex problem than single digits, please append it to your question. There are many ways to solve such problems in Python. In the above example I used the concept of the set, which can be very powerful to ensure that no duplication happens. You can convert the set back to a list easily b=list(a)

If I understand your question correctly, you have a list of words and you want to replace a certain word with another word? In many programming languages I think you would use a switch-case statement for something like this. This can be implemented in Python by using a dict:
switch = {
"a1" : "a",
"a2" : "a",
"a3" : "a",
"a4" : "a",
"b1" : "b",
"b2" : "b",
"b3" : "b",
"c1" : "c",
"c2" : "c",
"c3" : "c",
"d1" : "d",
"d2" : "d"
}
test_word = "d1"
answer = switch[test_word]
print(answer) #d
The bracket notation of [ ] used on a dict looks in the dict for a key matching the value within the brackets. It returns the corresponding value of that key in the dictionary. If it is not found it will raise a KeyError.
If you want to return a different value in the case that the key is not found, then you can use .get instead, like so:
switch.get(test_word, "not found")

Related

nested for loops and nested dictionary?

i am a new programmer trying to learn how to code still. I still don't quite know all of the technical info. I am trying to use a for loop on a list of dictionaries, and then inside of that loop, i want to create another loop that enumerates the dictionary keys. Inside of that loop, I then want to print the keys and values. I want the loop to break once the index reaches all of the points.
Dogs_in_Shelter = [{
"type" : "poodle",
"age" : "2",
"size" : "s",
},
{
"type" : "pug",
"age" : "7",
"size" : "m",
},
{
"type" : "lab",
"age" : "10",
"size" : "m",
}
]
for a in Dogs_in_Shelter:
for index, a in enumerate(Dogs_in_Shelter):
while (index <= 2):
print("{} {}".format(index,a["type"]))
index += 1
break
what prints out is:
0 poodle
1 pug
2 lab
0 poodle
1 pug
2 lab
0 poodle
1 pug
2 lab
I want only the first three lines (with the key and value) , not the repetitions.
Any help for a learner?
edit Yes there is an easier way without the nesting loops however i still need to have them nested. Thanks!
No need of extra for loop and while loop.
enumerate function gives you index and by passing type key you can get its value.
for index, a in enumerate(Dogs_in_Shelter):
print("{} {}".format(index, a["type"]))
Using nesting for loop.
Here I have used counter length = 0. Instead of while we should use if to check the counter.
length = 0
for a in Dogs_in_Shelter:
for index, a in enumerate(Dogs_in_Shelter):
if length <= 2 :
print("{} {}".format(index,a["type"]))
length += 1
You only need one for loop for what you want. while loop is also unnecessary. For example,
for index, dog in enumerate(Dogs_in_Shelter):
print(index, dog['type'])
For Python, we don't use upper letters for variables. FYI, Python Naming Convention
In this case, Dogs_in_Shelter should be dogs_in_shelter, or simply dogs.

python parse from a json array with duplicate names (mitre att&ck)

I am a novice trying to parse data from a repo of mitre att&ck json files and am stuck on how to parse data for one of the fields - attack phase names. They are stored in an array and there are sometimes duplicate names, see below:
"type": "attack-pattern",
"kill_chain_phases": [
{
"kill_chain_name": "mitre-attack",
"phase_name": "persistence"
},
{
"kill_chain_name": "mitre-attack",
"phase_name": "privilege-escalation"
}
],
If I try to return values for get_phase(attack.kill_chain_phases[0].phase_name), python only returns one value when there are sometimes multiple values, like privilege-escalation
If I try to mess around and use something like this get_phase(attack.kill_chain_phases[0].phase_name[0]) the output is the first character of one of the phase names c
If I try to do something like get_phase(attack_pattern.kill_chain_phases[1].phase_name) I get an out of index error...
Does anyone have an idea on how I can go about using python to grab these fields? Also does anyone know how to describe this data format and/or what I'm trying to do so I can try to search for solutions? Thanks in advance!
You're probably looking for something like a for loop. A simple example would be something like:
for attack in attack_pattern.kill_chain_phrases:
get_phrase(attack)
You will want to use a loop for this. Get the parent of the items you want to find all the values for, and then you can loop through and get all the children's values.
import json
json_string = """{
"type": "attack-pattern",
"kill_chain_phases": [
{
"kill_chain_name": "mitre-attack",
"phase_name": "persistence"
},
{
"kill_chain_name": "mitre-attack",
"phase_name": "privilege-escalation"
}
]
}
"""
parsed_json = json.loads(json_string)
# Loop through the parent "kill_chain_phases"
for kill_chain_phase in parsed_json["kill_chain_phases"]:
# print out the children "phase_name" values
print(kill_chain_phase["phase_name"]
You get the first character for get_phase(attack.kill_chain_phases[0].phase_name[0] because:
get_phase(attack.kill_chain_phases[0].phase_name[0] = "persistence"
Python then takes that string and treats it like a list:
["p", "e", "r", "s", "i", "s", "t", "e", "n", "c", "e"]
So phase_name[0] will show "p".
Hope that makes sense.
More info here

Loop through dictionary keys to get values based on input

1) In my program I start with prompting a user for input.
2) I would then like to loop through the users input to get all the characters in that string, query each character individually against the dictionaries keys.
3) If a character from the input matches a key in the dictionary, I want that key's value returned.
4) This needs to be repeated for each character and the result should print those values returned in a string
To try and explain further, here is my dictionary:
dataDict = {
"a":"1",
"b":"2",
"c":"3",
}
For example:
If my input is abc, my result should be 123
If my input is cba, my result should be 321
and so on...
So far, this works if the string is only one character using the below code.
If i enter two characters, it just returns nothing.
dataInput=input("Enter stuff: ")
for key,value in dataDict.items():
if dataInput == key:
print(value)
How can I acheive the results i'm after?
You shouldn't be looping over the dict to find the matching keys, that's very inefficient. A dict is designed to do fast lookups: you give it the key and it gives you the value. Eg, dataDict["a"] results in "1".
Also, as Tim Pietzcker mentions, doing if dataInput == key will only work if dataInput consists of a single letter, because it compares the whole dataInput string to key.
Here's a simple way to do the desired conversion. We do the lookups in a list comprehension, which creates a list of the converted values, and then we pass that list to .join to create a string. (I've changed the names of your variables to conform with the PEP-008 style guide).
data_dict = {
"a": "1",
"b": "2",
"c": "3",
}
data_input = "aabbccba"
s = ''.join([data_dict[c] for c in data_input])
print(s)
output
11223321
However, that's not safe: it will fail with KeyError if data_input contains a char that's not in the dictionary. Here's a better way: it adds an empty string if it gets a bad char.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '') for c in data_input])
print(s)
output
11223321
Alternatively, we could convert bad data to some special value, eg 0.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '0') for c in data_input])
print(s)
output
11022303210
Just for fun, here's a "functional" version. Guido would probably not approve of this one. :)
data_input = "aaxbbcycbaz"
print(''.join(filter(None, map(data_dict.get, data_input))))
11223321
You should be iterating over the input string, not the dictionary. Also, you might want to use .get() in case the users enters a characters that's not in the dictionary:
for letter in dataInput:
print(dataDict.get(letter,"X"))
This will print each letter on its individual line. If you want to print them in a single line, you can add the end="" parameter to the print function (and print an empty line after you're done).
The comparison you're doing would never work (in the first iteration, it would amount to if "abc" == "a", I hope that makes it obvious).
You're iterating through the wrong thing. You should be iterating through the input. You don't need to iterate through the dict, because you can just look up by key.

Comparing Swift and Python Dictionary objects

I'm trying to get familiar with Swift, so I'm doing some basic computations that I would normally do in Python.
I want to get a value from a dictionary using a key. In Python I would simply :
sequences = ["ATG","AAA","TAG"]
D_codon_aa = {"ATG": "M", "AAA": "R", "TAG": "*"}
for seq in sequences:
print D_codon_aa[seq]
>>>
M
R
*
When I try this in Swift.
let sequences = ["ATG","AAA","TAG"]
let D_codon_aa = ["ATG": "M", "AAA": "R", "TAG": "*"]
for seq in sequences
{
var codon = D_codon_aa[seq]
println(codon)
}
>>>
Optional("M")
Optional("R")
Optional("*")
1) What is Optional() and why is it around the dictionary value?
2) Why can't I make a dictionary with multiple types of objects inside?
In Python I can do this:
sequence= {'A':0,'C':1, 'G':'2', 'T':3.0}
In Swift I can't do this:
let sequences = ["A":0,"C":1, "G":"2", "T":3.0]
1:
Look at the declaration of the dictionarys subscript:
subscript(key: Key) -> Value?
It returns an optional, since you can use any key you want in subscripts, but they might not associated with values, so in that case it returns nil, otherwise the value wrapped in an optional.
2: Actually, you can, if you define your dictionary as for eg. ["String": AnyObject], and now you can associate keys with values, thats conforms to the AnyObject protocol.
Updated
And your example let sequences = ["A":0,"C":1, "G":"2", "T":3.0] compiles fine in Xcode 6.1.1.

Query Filter for value from multidimensional dictionary?

I'm new to Python/Django and i have a question.
I need to get a QuerySet filtered by a Value from a multidimensional dictionary (JSONField).
So far, I got this:
def make_cond(name, value):
from django.utils import simplejson
cond = simplejson.dumps({key:value})[1:-1] # remove '{' and '}'
return ' ' + cond # avoid '"'
Post.objects.filter(JSONField__contains=make_cond('key', 'value'))
That works, but only for the 1st dimension of the dict.
How can I reach the other dimensions?
SQL can't help you with that.
Given an arbitrary json object whose serialization might look like this,
'{"a": {"c": "C", "b": "B"}, "c": {}, "b": {"e": "E", "d": "D"}}'
you'd have to construct a LIKE clause that matches, say, the {"a", then another { and then "b": "B" without caring what's in place of "c": "C". A LIKE clause supports wildcards only before and after, so you can't get what you want.
It's possible you could figure it out with a fulltext index; you could try Haystack or Sphinx for that.
The correct tool for the job, though, is a NoSQL database like mongodb.

Categories