Python - match dictionary value within string & print key in string order - string

I asked a similar question to this earlier on but Im still having a hard time figuring this out. I have the following code:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '401'}
string = '401203010'
text = ''
for i, j in d.items():
if j in string:
text += i
print(text) #prints karp
desired output: park
the output I get is karp, however I would like the output to be in order of value match in the string, Thanks!

try this maybe?
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
keylen = len(''.join(d.keys()))
while len(text) != keylen:
found_val = 0
for i, j in d.items():
jl = len(j)
if string[:jl] == j:
text += i
string = string[jl:]
found_val += 1
if found_val == 0:
break
print(text)
for the sake of clarity, this is really not an algorithm you want to use here. For example one of the downfalls is if it isn't guaranteed that a part of the string will be in the dictionary values then the loop will never end. I don't want to spend the mental resources to fix that potential pitfall because I have some reading to do but perhaps you can figure out a way around it.
edit, never mind that wasn't that difficult but you should test various edge cases.

You could first split up string into substrings of 2, and then switch the keys ad values of d in a temporary dictionary, then just add the values from that:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
split_string = [string[i:i+2] for i in range(0, len(string), 2)]
# ['40', '20', '30', '10']
new_dict = dict((y,x) for x,y in d.items())
# {'30': 'r', '10': 'k', '20': 'a', '40': 'p'}
text = "".join(new_dict[string] for string in split_string)
print(text)
# park

Related

Values in a list to a range()

I have a user input which comes in as follows:
j = ['1', '2', '3', '4', '5-6', '7-9']
I want to go through this list, identify any 'ranges' such as 7-8, or 5-99 etc.
With these remove the - and put the first and second values into range()
So far I have the following, I just can't figure out how to get the values into the right place, perhaps I need to select the number before the - and after the - ?
for item in j:
if "-" in item:
item = item.split("-")
# list(map(str, range(244, 247)))
for r in item:
print(r)
print('next')
# something like this?
list(map(str, range(int(item[0]), int(item[1]))))
EDIT
Taking into account jonrsharpe's comment:
for item in j:
if "-" in item:
start, stop = item.split("-")
print('start:' + start + ' end: ' + stop)
list(map(str, range(int(start), int(stop))))
This returns a type error TypeError: 'str' object is not callable
Assuming the output expected is j = [1, 2, 3, 4, 5, 6, 7, 8, 9]
You can create a blank list, process each element depending on whether or not it has a "-"
l = ['1', '2', '3', '4', '5-6', '7-9']
ll = []
for element in l:
if '-' in element:
sublist = element.strip().split('-')
sublist = list(range(int(sublist[0]), int(sublist[1]) + 1))
ll += sublist
else:
ll.append(int(element))
One approach is to create a list of items for both single numbers and ranges, and then use this as the argument to range:
j = ['1', '2', '3', '4', '5-6', '7-9']
for item in j:
if '-' in item:
rng = [int(x) for x in item.split('-')]
else:
# Start and stop are the same
rng = [int(item)] * 2
# Pad the stop number
rng[1] += 1
for i in range(*rng):
print(i)

What's the one liner to split a string to dictionary with default value in python3?

I have a input string input_str = 'a=1;b=2;c' and I want to split it into dictionary as {'a':1, 'b':2, 'c': '.'}
input_str = 'a=1;b=2;c'
default = '.'
output = dict(s.split('=') if '=' in s else {s ,default} for s in input_str.split(';'))
print(output)
{'a': '1', 'b': '2', '.': 'c'}
# Output I want:
{'a': '1', 'b': '2', 'c': '.'}
Following code works.But I was looking for a one liner with dict comprehension.
my_result = {}
input_str = 'a=1;b=2;c'
for s in input_str.split(';'):
if '=' in s:
key, val = s.split('=')
my_result[key] = val
else:
my_result[s] = '.'
I noticed that else condition in above code {s ,default} is treated as set. How to convert it into dictionary.
As you noted, {s, default} defines a set, and the order of sets is undefined.
All you need to do to remedy this is to use a list instead.
dict(s.split('=', 1) if '=' in s else [s, default] for s in input_str.split(';'))
Note, this is unlikely to be very useful in real-life unless you have very restricted requirements. What happens if you want to include a value that contains a ';' character?
By changing the first split() call to have , 1, this means that the value will only ever be split once, no matter how many '=' characters there are.
For example, trying to parse an input of: a=bad=value;b=2 would raise a ValueError.

Reordering character triplets in Python

I've been trying to solve this homework problem for days, but can't seem to fix it. I started my study halfway through the first semester, so I can't ask the teacher yet and I hope you guys can help me. It's not for grades, I just want to know how.
I need to write a program that reads a string and converts the triplets abc into bca. Per group of three you need to do this. For examplekatzonbecomesatkonz`.
The closest I've gotten is this:
string=(input("Give a string: "))
for i in range(0, len(string)-2):
a = string[i]
b = string[i + 1]
c = string[i + 2]
new_string= b, c, a
i+=3
print(new_string)
The output is:
('a', 't', 'k')
('t', 'z', 'a')
('z', 'o', 't')
('o', 'n', 'z')
The code below converts for example "abc" to "bca". It works for any string containing triplets. Now, if input is "abcd", it is converted to "bcad". If you input "katzon", it is converted to "atkonz". This is what I understood from your question.
stringX = input()
# create list of words in the string
listX = stringX.split(" ")
listY = []
# create list of triplets and non-triplets
for word in listX:
listY += [[word[i:i+3] for i in range(0, len(word), 3)]]
# convert triplets, for example: "abc" -> "bca"
for listZ in listY:
for item in listZ:
if len(item)==3:
listZ[listZ.index(item)] = listZ[listZ.index(item)][1:] + listZ[listZ.index(item)][0]
listY[listY.index(listZ)] = "".join(listZ)
# create final string
stringY = " ".join(listY)
print(stringY)

How do I join portions of a list in Python

Trying to join only portions of a large list that has numbers in it. For example:
h = ['9 This is the way this is the way 10 to program a string 11 to program a string']
##I've tried...
h[0].split()
z = []
h = ['9', 'This', 'is', 'the', 'way', 'this', 'is', 'the', 'way', '10', 'to', 'program', 'a', 'string', '11', 'to', 'program', 'a', 'string']
for i in h:
while i != '10':
z.append(i)
But the program runs an infinite loop. I've also tried if statements, if i != '10' then z.append(i). Basically, I have large portions of scripture that is in a list as a single string and I'd like to quickly extract the verses and put them in their own separate list. Thank you
Edit: I've tried...
h= ['9 nfnf dhhd snsn nana na 10 hfhf gkg utu 11 oeoe ldd sss', 'kgk hfh']
y = h[0].split()
print (y)
z = []
for i in y:
if i != "10":
z.append(i)
break
print (z)
Output is the split list and 'z' prints '9' only. I've also changed the break to the correct indentation for the 'for' loop
First of all, use the result you get from h[0].split(). You can do this by using h = h[0].split()
Now, lets get to the loop. It's going into an infinite loop because the for loop is picking the first i which is "9" and then while i != "10", it keeps appending i to z. i will never equal "10". Thus, the infinite loop. I think what you want here is:
for i in h:
if i != "10":
z.append(i)
else:
break
This will append every value of h into z until i is equal to "10". Let me know if you need more help and I'll be happy to edit!
Try this for extracting all numbers in z:
h = ['9 This is the way this is the way 10 to program a string 11 to program a string']
##I've tried...
h = h[0].split()
z = []
for i in h:
try:
z.append(eval(i))
except:
pass
print z
output:
[9, 10, 11]
[Finished in 0.0s]

Musical note string (C#-4, F-3, etc.) to MIDI note value, in Python

The code in my answer below converts musical notes in strings, such as C#-4 or F-3, to their corresponding MIDI note values.
I am posting this because I am tired of trying to dig it up online every time I need it. I'm sure I'm not the only one who can find a use for it. I just wrote this up — it is tested and correct. It's in Python, but I feel that it pretty close to universally understandable.
#Input is string in the form C#-4, Db-4, or F-3. If your implementation doesn't use the hyphen,
#just replace the line :
# letter = midstr.split('-')[0].upper()
#with:
# letter = midstr[:-1]
def MidiStringToInt(midstr):
Notes = [["C"],["C#","Db"],["D"],["D#","Eb"],["E"],["F"],["F#","Gb"],["G"],["G#","Ab"],["A"],["A#","Bb"],["B"]]
answer = 0
i = 0
#Note
letter = midstr.split('-')[0].upper()
for note in Notes:
for form in note:
if letter.upper() == form:
answer = i
break;
i += 1
#Octave
answer += (int(midstr[-1]))*12
return answer
NOTES_FLAT = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']
NOTES_SHARP = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
def NoteToMidi(KeyOctave):
# KeyOctave is formatted like 'C#3'
key = KeyOctave[:-1] # eg C, Db
octave = KeyOctave[-1] # eg 3, 4
answer = -1
try:
if 'b' in key:
pos = NOTES_FLAT.index(key)
else:
pos = NOTES_SHARP.index(key)
except:
print('The key is not valid', key)
return answer
answer += pos + 12 * (int(octave) + 1) + 1
return answer

Resources