I want to write a loop function that go through each letter in my list called original.
original = ['ABCD', 'DCBA', 'AAAA', 'AABB']
letters = ['A', 'B', 'C', 'D']
p = 1
for o in original: # loop through the original list
for i in range(0,len(o)): # loop through each letter in selected list
if random.randint(1,10) == p: #if this gives me the probability that is met
# I want to change the current letter on the current index to
# something else different from the letter list by random (maybe random.choice)
Im new to python please can you advice.
I dont want to use class or any other library but random please
First, the zero in
for i in range(0, len(o))
is redundant. You want to give random.choice a list of letters that include everything in letters minus the current letter. The fastest way I can think of doing this is with a set:
newletters = list(set(letters).difference(o[i])
Now you have a list that includes all the letters in "letters" except for the letter at o[i].
To assign the letter (after you get it from random.choice), turn your "original" word into a list:
o_list = list(o)
and assign it as
l = random.choice(newletters)
o_list[i] = l
new_word = "".join(o_list)
As for actually inserting that new word back into your list of originals, you would have to know the index of the old word - I would use enumerate to do this:
original = ['ABCD', 'DCBA', 'AAAA', 'AABB']
letters = ['A', 'B', 'C', 'D']
p = 1
for index, o in enumerate(original): # loop through the original list
for i in range(len(o)): # loop through each letter in selected list
if random.randint(1,10) == p:
newletters = list(set(letters).difference(o[i])
o_list = list(o)
l = random.choice(newletters)
o_list[i] = l
new_word = "".join(o_list)
original[index] = new_word
In python, you can not modify strings at all. You can get letters by index, select specific strings, but not modify them. To change the said list you can use original.pop(o) and add the said edited string in the list with original.append('AB" + random.choice(letters) + 'C' as you said. To be more clear: you use list.append(element) to add element to list and you use list.pop(element) to remove element from list. Again, you can never edit strings in python, you can only create new ones and store the edited old ones, for example, new_string = old_string[:4], this particular code will store all the characters in old_string, up to index 4 into the new string. Really hope I helped!
Assuming you want to update original
import random
original = ['ABCD', 'DCBA', 'AAAA', 'AABB']
letters = ['A', 'B', 'C', 'D']
p = 1
for i, o in enumerate(original):
new_letters = [] # updated letters for word o
for c in o:
if random.randint(1,10) == p:
t = letters[:] # copy of letters
t.remove(c) # remove letter from copy (so letters remains unchanged)
new_letters.append(random.choice(t)) # choice over remaining letters
else:
new_letters.append(c)
original[i] = ''.join(new_letters) # convert newsletters list to string
# and replace in original
print(original)
Related
I am making a program that has two lists (in Python), and each list contains 5 different letters. How do I make it so that any index number I choose for both lists gets compared and uppercase a letter if the condition is true? If the first two values in the list are the same (in my case a lowercase letter), then I want the letter in the second list to become uppercase.
example/attempt (I don't know what I'm doing):
if list1[0] = list2[0]:
upper(list2[0])
Without an example of you input and output, it's difficult to understand what your goal is, but if your goal is to use .upper() on any string in list2 where list1[i] and list2[i] are equal, you can use a combination of zip and enumerate to compare, and then assign the value of list2[i] to the uppercase string like so:
list1 = ['a', 'b', 'c']
list2 = ['a', 'p', 'q']
for i, (x, y) in enumerate(zip(list1, list2)):
if x == y:
list2[i] = y.upper()
print(list2)
Output:
['A', 'p', 'q']
I think you could use something like this:
def compare_and_upper(lst1, lst2):
for i in range(len(lst1)):
if lst1[i].upper() == lst2[i].upper():
return lst1[i].upper()
return None
This is not a full solution of your problem, more of a representation of how to do the comparisons, which you can then reuse / modify to do the solution you want in the end.
import string
from random import choices
def create_random_string(str_len=10):
# k = the number of letters that we want it to return.
return "".join(choices(string.ascii_lowercase, k=str_len))
def compare(str_len=10):
# Create the two strings that we want to compare
first_string = create_random_string(str_len)
second_string = create_random_string(str_len)
# comp_string will hold the final string that we want to return.
comp_string = ""
# Because the length of the strings are based on the variable str_len,
# we can use the range of that number to iterate over our comparisions.
for i in range(str_len):
# Compares the i'th position of the strings
# If they match, then add the uppercase version to comp_string
if first_string[i] == second_string[i]:
comp_string += first_string[i].upper()
else:
comp_string += "-"
return comp_string
for _ in range(10):
print(compare(20))
Sample output:
--------------------
---AS---D---------D-
----W--Q--------E---
--------------------
-----------------E--
------T-------------
--------------------
-------------P------
-----S--------------
--B-----------------
I am trying to do slicing in string "abcdeeefghij", here I want the slicing in such a way that whatever input I use, i divide the output in the format of a list (such that in one list element no alphabets repeat).
In this case [abcde,e,efghij].
Another example is if input is "aaabcdefghiii". Here the expected output is [a,a,acbdefghi,i,i].
Also amongst the list if I want to find the highest len character i tried the below logic:
max_str = max(len(sub_strings[0]),len(sub_strings[1]),len(sub_strings[2]))
print(max_str) #output - 6
which will yield 6 as the output, but i presume this logic is not a generic one: Can someone suggest a generic logic to print the length of the maximum string.
Here is how:
s = "abcdeeefghij"
l = ['']
for c in s: # For character in s
if c in l[-1]: # If the character is already in the last string in l
l.append('') # Add a new string to l
l[-1] += c # Add the character to either the last string, either new, or old
print(l)
Output:
['abcde', 'e', 'efghij']
Use a regular expression:
import re
rx = re.compile(r'(\w)\1+')
strings = ['abcdeeefghij', 'aaabcdefghiii']
lst = [[part for part in rx.split(item) if part] for item in strings]
print(lst)
Which yields
[['abcd', 'e', 'fghij'], ['a', 'bcdefgh', 'i']]
You would loop over the characters in the input and start a new string if there is an existing match, otherwise join them onto the last string in the output list.
input_ = "aaabcdefghiii"
output = []
for char in input_:
if not output or char in output[-1]:
output.append("")
output[-1] += char
print(output)
To avoid repetition of alphabet within a list element repeat, you can greedily track what are the words that are already in the current list. Append the word to your answer once you detected a repeating alphabet.
from collections import defaultdict
s = input()
ans = []
d = defaultdict(int)
cur = ""
for i in s:
if d[i]:
ans.append(cur)
cur = i # start again since there is repeatition
d = defaultdict(int)
d[i] = 1
else:
cur += i #append to cur since no repetition yet
d[i] = 1
if cur: # handlign the last part
ans.append(cur)
print(ans)
An input of aaabcdefghiii produces ['a', 'a', 'abcdefghi', 'i', 'i'] as expected.
In the challenge you are asked to find the length of the longest substring that consists of the same letter. For example, line "aaabbcaaaa" contains four substrings with the same letters "aaa", "bb","c" and "aaaa". The last substring is the longest one which makes it an answer. Input: String. Output: Int. Example:
long_repeat('sdsffffse') == 4
long_repeat('ddvvrwwwrggg') == 3
Here is my code :
def long_repeat(text):
text = list(text)
counter = []
c = []
for i in range(len(text)):
if text[0] == text[1]:
c.append(text.pop(0))
else:
counter.append(c)
c = []
print text # should be empty
print counter # should contain a lists of the repeated letters
Output:
>>>long_repeat('aaabbccc')
['a', 'b', 'b', 'c', 'c', 'c', 'c']
[['a', 'a'], [], [], [], [], [], []]
why the loop stopes when it finishes the first letter which is 'a' in this case?
The loop does not stop. Your else statement does not move the list forward (no pop here). By the way, your logic is not quite correct. And also, it is not a good idea to pop the character and then collect it each turn. You can use integers to record all necessary information you need, including position, current count, maximum count and etc.
When test[0] != text[1] e.g when input is at "ab" you aren't appending the a to the c variable
In addition, Python string has no "pop" method hence why it's exiting out (pay close attention to error returned).
Use something like this for pop
c.append(text[-1])
text = text[:-1]
I am trying to append to lists nested in a dictionary so I can see which letters follow a letter. I have the desired result at the bottom I would like to get. Why is this not matching up?
word = 'google'
word_map = {}
word_length = len(word)
last_letter = word_length - 1
for index, letter in enumerate(word):
if index < last_letter:
if letter not in word_map.keys():
word_map[letter] = list(word[index+1])
if letter in word_map.keys():
word_map[letter].append(word[index+1])
if index == last_letter:
word_map[letter] = None
print word_map
desired_result = {'g':['o', 'l'], 'o':['o', 'g'], 'l':['e'],'e':None}
print desired_result
Use the standard library to your advantage:
from itertools import izip_longest
from collections import defaultdict
s = 'google'
d = defaultdict(list)
for l1,l2 in izip_longest(s,s[1:],fillvalue=None):
d[l1].append(l2)
print d
The first trick here is to yield the letters pair-wise (with a None at the end). That's exactly what we do with izip_longest(s,s[1:],fillvalue=None). From there, it's a simple matter of appending the second letter to the dictionary list which corresponds to the first character. The defaultdict allows us to avoid all sorts of tests to check if the key is in the dict or not.
if letter not in word_map.keys():
word_map[letter] = list(word[index+1])
# now letter IS in word_map, so this also executes:
if letter in word_map.keys():
word_map[letter].append(word[index+1])
You meant:
if letter not in word_map.keys():
word_map[letter] = list(word[index+1])
else:
word_map[letter].append(word[index+1])
Another thing: what if the last letter also occurs in the middle of the word?
Question: DO NOT USE SETS IN YOUR FUNCTION: Uses lists to return a list of the common letters in the first and last names (the intersection) Prompt user for first and last name and call the function with the first and last names as arguments and print the returned list.
I can't figure out why my program is just printing "No matches" even if there are letter matches. Anything helps! Thanks a bunch!
Code so far:
import string
def getCommonLetters(text1, text2):
""" Take two strings and return a list of letters common to
both strings."""
text1List = text1.split()
text2List = text2.split()
for i in range(0, len(text1List)):
text1List[i] = getCleanText(text1List[i])
for i in range(0, len(text2List)):
text2List[i] = getCleanText(text2List[i])
outList = []
for letter in text1List:
if letter in text2List and letter not in outList:
outList.append(letter)
return outList
def getCleanText(text):
"""Return letter in lower case stripped of whitespace and
punctuation characters"""
text = text.lower()
badCharacters = string.whitespace + string.punctuation
for character in badCharacters:
text = text.replace(character, "")
return text
userText1 = raw_input("Enter your first name: ")
userText2 = raw_input("Enter your last name: ")
result = getCommonLetters(userText1, userText2)
numMatches = len(result)
if numMatches == 0:
print "No matches."
else:
print "Number of matches:", numMatches
for letter in result:
print letter
Try this:
def CommonLetters(s1, s2):
l1=list(''.join(s1.split()))
l2=list(''.join(s2.split()))
return [x for x in l1 if x in l2]
print CommonLetters('Tom','Dom de Tommaso')
Output:
>>> ['T', 'o', 'm']
for letter in text1List:
Here's your problem. text1List is a list, not a string. You iterate on a list of strings (['Bobby', 'Tables'] for instance) and you check if 'Bobby' is in the list text2List.
You want to iterate on every character of your string text1 and check if it is present in the string text2.
There's a few non-pythonic idioms in your code, but you'll learn that in time.
Follow-up: What happens if I type my first name in lowercase and my last name in uppercase? Will your code find any match?
Prior to set() being the common idiom for duplicate removal in Python 2.5, you could use the conversion of a list to a dictionary to remove duplicates.
Here is an example:
def CommonLetters(s1, s2):
d={}
for l in s1:
if l in s2 and l.isalpha():
d[l]=d.get(l,0)+1
return d
print CommonLetters('matteo', 'dom de tommaso')
This prints the count of the common letters like so:
{'a': 1, 'e': 1, 'm': 1, 't': 2, 'o': 1}
If you want to have a list of those common letters, just use the keys() method of the dictionary:
print CommonLetters('matteo', 'dom de tommaso').keys()
Which prints just the keys:
['a', 'e', 'm', 't', 'o']
If you want upper and lower case letters to match, add the logic to this line:
if l in s2 and l.isalpha():