Python - dictionary print the key as many times as his value - python

I want to print out all the letters in my dictionary (seen at the last line of my code) the problem is that the output is aqlmui now. But as you guys can see the l in my dictionary is having a value of 2 so I want to print that out 2 times. so the output of my program should be: aqllmui.
Help would be appreciated a lot! :)
def display_hand(hand):
row = ''
for letter in hand:
row += letter
#I think i need to put an if statement here but I just don't know how to do it
print row
display_hand({'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1})

You can also try print "".join(k*v for (k,v) in s.iteritems()).
Here k*v for (k,v) in s.iteritems() returns a list of key*value like ["a","i","m","ll","q","u"] and "".join(list) will join that list to make a string.

just do:
row += letter * hand[letter]

You can use string/int multiplication to perform multiple concatenations
for letter in hand:
row += letter * hand[letter]
Or a little more clearly and efficiently:
for letter, count in hand.iteritems(): # Use hand.items() in Python 3
row += letter * count

Related

Given a string, S , print its even-indexed and odd-indexed characters as 2 space-separated strings on a single line

I know it can be simply done through string slicing but i want to know where is my logic or code is going wrong. Please Help!
S=input()
string=""
string2=""
list1=[]
list1[:0]=S
for i in list1:
if(i%2==0):
string=string+list1[i]
else:
string2=string2+list1[i]
print(string," ",string2)
Here's my code. Firstly i stored each character of string in the list and went by accessing the odd even index of the list.
But i'm getting this error
if(i%2==0):
TypeError: not all arguments converted during string formatting
You are iterating over characters, not indices, so your modulo is incorrect, equivalent to:
i = "a"
"a" % 2 == 0
You want to use enumerate
for idx, letter in enumerate(list1):
if(idx%2 == 0)
string += letter
You don't need to use an intermediate list: just iterate over the input string directly. You also need to use for i in range(len(original)) rather than for i in original, because you need to keep track of whether a given character is at an odd or an even index. (I've gone ahead and renamed some of the variables for readability.)
S = input()
even_index_characters = ""
odd_index_characters = ""
for i in range(len(S)):
if i % 2 == 0:
even_index_characters += S[i]
else:
odd_index_characters += S[i]
print(f"{even_index_characters} {odd_index_characters}")

How to extract words from repeating strings

Here I have a string in a list:
['aaaaaaappppppprrrrrriiiiiilll']
I want to get the word 'april' in the list, but not just one of them, instead how many times the word 'april' actually occurs the string.
The output should be something like:
['aprilaprilapril']
Because the word 'april' occurred three times in that string.
Well the word actually didn't occurred three times, all the characters did. So I want to order these characters to 'april' for how many times did they appeared in the string.
My idea is basically to extract words from some random strings, but not just extracting the word, instead to extract all of the word that appears in the string. Each word should be extracted and the word (characters) should be ordered the way I wanted to.
But here I have some annoying conditions; you can't delete all the elements in the list and then just replace them with the word 'april'(you can't replace the whole string with the word 'april'); you can only extract 'april' from the string, not replacing them. You can't also delete the list with the string. Just think of all the string there being very important data, we just want some data, but these data must be ordered, and we need to delete all other data that doesn't match our "data chain" (the word 'april'). But once you delete the whole string you will lose all the important data. You don't know how to make another one of these "data chains", so we can't just put the word 'april' back in the list.
If anyone know how to solve my weird problem, please help me out, I am a beginner python programmer. Thank you!
One way is to use itertools.groupby which will group the characters individually and unpack and iterate them using zip which will iterate n times given n is the number of characters in the smallest group (i.e. the group having lowest number of characters)
from itertools import groupby
'aaaaaaappppppprrrrrriiiiiilll'
result = ''
for each in zip(*[list(g) for k, g in groupby('aaaaaaappppppprrrrrriiiiiilll')]):
result += ''.join(each)
# result = 'aprilaprilapril'
Another possible solution is to create a custom counter that will count each unique sequence of characters (Please be noted that this method will work only for Python 3.6+, for lower version of Python, order of dictionaries is not guaranteed):
def getCounts(strng):
if not strng:
return [], 0
counts = {}
current = strng[0]
for c in strng:
if c in counts.keys():
if current==c:
counts[c] += 1
else:
current = c
counts[c] = 1
return counts.keys(), min(counts.values())
result = ''
counts=getCounts('aaaaaaappppppprrrrrriiiiiilll')
for i in range(counts[1]):
result += ''.join(counts[0])
# result = 'aprilaprilapril'
How about using regex?
import re
word = 'april'
text = 'aaaaaaappppppprrrrrriiiiiilll'
regex = "".join(f"({c}+)" for c in word)
match = re.match(regex, text)
if match:
# Find the lowest amount of character repeats
lowest_amount = min(len(g) for g in match.groups())
print(word * lowest_amount)
else:
print("no match")
Outputs:
aprilaprilapril
Works like a charm
Here is a more native approach, with plain iteration.
It has a time complexity of O(n).
It uses an outer loop to iterate over the character in the search key, then an inner while loop that consumes all occurrences of that character in the search string while maintaining a counter. Once all consecutive occurrences of the current letter have been consumes, it updates a the minLetterCount to be the minimum of its previous value or this new count. Once we have iterated over all letters in the key, we return this accumulated minimum.
def countCompleteSequenceOccurences(searchString, key):
left = 0
minLetterCount = 0
letterCount = 0
for i, searchChar in enumerate(key):
while left < len(searchString) and searchString[left] == searchChar:
letterCount += 1
left += 1
minLetterCount = letterCount if i == 0 else min(minLetterCount, letterCount)
letterCount = 0
return minLetterCount
Testing:
testCasesToOracles = {
"aaaaaaappppppprrrrrriiiiiilll": 3,
"ppppppprrrrrriiiiiilll": 0,
"aaaaaaappppppprrrrrriiiiii": 0,
"aaaaaaapppppppzzzrrrrrriiiiiilll": 0,
"pppppppaaaaaaarrrrrriiiiiilll": 0,
"zaaaaaaappppppprrrrrriiiiiilll": 3,
"zzzaaaaaaappppppprrrrrriiiiiilll": 3,
"aaaaaaappppppprrrrrriiiiiilllzzz": 3,
"zzzaaaaaaappppppprrrrrriiiiiilllzzz": 3,
}
key = "april"
for case, oracle in testCasesToOracles.items():
result = countCompleteSequenceOccurences(case, key)
assert result == oracle
Usage:
key = "april"
result = countCompleteSequenceOccurences("aaaaaaappppppprrrrrriiiiiilll", key)
print(result * key)
Output:
aprilaprilapril
A word will only occur as many times as the minimum letter recurrence. To account for the possibility of having repeated letters in the word (for example, appril, you need to factor this count out. Here is one way of doing this using collections.Counter:
from collections import Counter
def count_recurrence(kernel, string):
# we need to count both strings
kernel_counter = Counter(kernel)
string_counter = Counter(string)
# now get effective count by dividing the occurence in string by occurrence
# in kernel
effective_counter = {
k: int(string_counter.get(k, 0)/v)
for k, v in kernel_counter.items()
}
# min occurence of kernel is min of effective counter
min_recurring_count = min(effective_counter.values())
return kernel * min_recurring_count

Count the number of times a string appears in the reverse position of the string

I am trying to figure out a way that you can count how many times a letter appears in the exact opposite position. For example:
word = 'ABXCEEVHBA' --> The correct output give me 3 because A is first and last. B is second and second from last and so forth.
I have found an answer that gives me the correct result but I was wondering if there is a more elegant way to do this ideally with no modules.
word = 'ABXCEEVHBA'
reverse = ''.join(reversed(word))
sum =0
for i in range(len(word)):
if word[i]==reverse[i]:
sum+=1
print(int(sum/2))
Believe this shall do it:
>>> count = 0
>>> for i in range(len(word)//2): # meet half-way.
if word[i] == word[~i]:
count += 1
>>> count
3
You can do it with zip by combining the string with the inverse of itself:
sum(a==b for a,b in zip(word,reversed(word)))//2

Can someone explain this word frequency count, please?

I'm taking the MIT DS&A algorithm course and on the document distance problem, we have to parse a file into a list of words, then count the frequency of each word in the file. I have a hard time comprehending the following function:
def count_frequency(word_list):
"""
Return a list giving pairs of form: (word,frequency)
"""
L = []
for new_word in word_list:
for entry in L:
if new_word == entry[0]:
entry[1] = entry[1] + 1
break
else:
L.append([new_word,1])
return L
Why do we compare new_word to entry[0]?
a. What if L is empty? What do we compare new_word to?
b. Why do we compare new_word to entry[0] specifically? Why don't we do something like
if new_word in L
c. Why do we need to use break?
Why is the else block 1 tab to the right of the earlier if block? When I tried to indent the else block, an indentation error would show up.
Thank you for your help!
The list L contains two-item entries due to L.append([new_word,1]). If L is empty the for would not be entered, so there is no problem with entry[0].
entry[0] is a word and entry[1] is a count. You can't say if new_word in L because it is not just a list of strings.
break stops the for once a word is found.
for/else is a thing in Python. The else runs if the for completes without interruption (a break in this case). If new_word isn't in L, the for won't break and the new word and a count of 1 is added to L.
FYI, the built-in collections.Counter() would return similar results.

How to remove characters from the odd numbered string?

If I have a string like this: ABCDE
I want to read two characters at a time (AB then CD) and remove the remaining characters (E) which cannot be read in tuples or in two's. How would I remove those characters?
I have this code below so far:
s = 'ABCDE'
for (first, second) in zip(s[0::2], s[1::2]):
if not first or not second:
if first:
s.replace(first, '')
continue
else:
s.replace(second, '')
continue
print first, second
print s
This code prints (A B C D) which is good but I want to remove that extra E in the for loop which I am trying to do with the if statement. I check if the either the first or second variable of the tuple is an empty string and then remove whichever one isn't an empty string from the original s variable.
This above code doesn't seem to work. Does anyone have a different suggestion or how I can improve this?
If you want to remove the last character in case the string's length is odd:
word = "ABCDE"
if len(word) % 2 == 1:
word = word[:-1]
Now if you want to read the characters two at a time, here is a more instinctive way:
for i in range(len(word) // 2):
print(word[2*i:2*i+2])
The latter will even drop the last character for you.
str = "ABCDE"
for i, k in zip(str[::2], str[1::2]):
print(i + k)
Outputs:
AB
CD

Categories

Resources