My code:
seperated = startContent.split(' ')
seperatedNum = len(seperated)
#Ask for user input
for word in seperated and for i in seperatedNum:
if word == 'ADJECTIVE':
seperated[i] = input('Enter an adjective:')
elif word == 'NOUN':
seperated[i] = input('Enter a noun:')
elif word == 'ADVERB':
seperated[i] = input('Enter an adverb:')
elif word == 'VERB':
seperated[i] = input('Enter a verb:')
Basically asking the user input each time they run into one of the following words (there can be multiple of each).
I get my sentence, split it into a list with split command. And run the loop for each word. I want to then edit the list using list[x] = 'replacement' method.
The word in seperated, returns the listitem. So I need another argument passed to it, e.g i in len(list) to then get the accurate index of the word. I can't use list.index(str) because it returns the first index of the string when there are multiple iterations of the text.
You're looking for a way to pass multiple parameters in a for loop: There is nothing special about a for loop in this regard. The loop will iterate over a given sequence and will, each iteration, assign the current element to the given left-hand side.
for LEFT_HAND_SIDE in SEQUENCE
Python also supports "automatic" unpacking of sequences during assigments, as you can see in the following example:
>>> a, b = (4, 2)
>>> a
4
>>> b
2
In conclusion, you can just combine multiple variables on the left-hand side in your for loop with a sequence of sequences:
>>> for a, b in [(1, 2), (3, 4)]:
... print(a)
... print(b)
...
1
2
3
4
That for loop had two assignments a, b = (1, 2) and a, b = (3, 4).
In you specific case, you want to combine the value of an element in a sequence with its index. The built-in function enumerate comes in handy here:
>>> enumerate(["x", "y"])
<enumerate object at 0x7fc72f6685a0>
>>> list(enumerate(["x", "y"]))
[(0, 'x'), (1, 'y')]
So you could write your for loop like this:
for i, word in enumerate(seperated)
Related
Write a function called word_freq(text) which takes one string
argument. This string will not have any punctuation. Perform a count
of the number of 'n' character words in this string and return a list
of tuples of the form[(n, count), (n-1, count) ...] in descending
order of the counts. For example:
Example: word_freq('a aaa a aaaa')
Result: [(4, 1), (3, 1), (1, 2)]
Note: that this does not show anything for the 2 character words. str1
= 'a aaa a aaa' str.split(str1) str.count(str1)
def word_freq(str): Python code to find frequency of each word
I tried this
text = 'a aaa a aaaa'
def word_freq(str):
tuple = ()
count = {}
for x in str:
if x in count.keys():
count[x] += 1
else:
count[x] = 1
print(count)
def count_letters(word):
char = "a"
count = 0
for c in word:
if char == c:
count += 1
return count
word_freq(text)
The code below does what you want. Now I'll explain how it works. before anything, we will make a dictionary called "WC" which will hold the count of each n-character-word in our sentence. now we start. first of all, it receives a string from user. then it takes the string and using split(), it turns the string into a LIST of words. then for each word it checks its length, if it is 2, it ignores it. otherwise, it will add 1 to the count of that n-character word in our dictionary.
after every word is checked, we use wc.items() to turn our dictionary into a list of tuples. Each element in the list is a tuple that contains data for each word. each tuple has 2 elements. the first is number of charatcers of each word and the second element is the number of times it existed in the sentence. with that out of the way, Now all we need is to do is sort this list based on the character counts in reverse (from high char count to low char count). we do that using the sorted function. we sort based on x[0] which means the first element of each tuple which is the character count for each word. Finally, we return this list of tuples. You can print it.
if anything is unclear, let me know. also, you can put print() statements at every line so you can better understand what is happening.
here's the code, I hope it helps:
inp = input("Enter your text: ")
def word_count(inp_str):
wc = {}
for item in inp_str.strip().split():
if len(item) == 2:
continue
wc[len(item)] = wc.get(len(item), 0) + 1
return sorted(wc.items(), key=lambda x: x[0], reverse = True)
print(word_count(inp))
I have been trying to make the even letters in a string become upper-cased and the odd letters to become lower-cased with a function, like so:
def myfunc('apple'):
#OUTPUTS: 'ApPlE'
This is what I made:
def myfunc(mystring):
stringList = [letter for letter in mystring]
for letter in stringList[1::2]:
stringList[stringList.index(letter)] = letter.lower()
for letter in stringList[::2]:
stringList[stringList.index(letter)] = letter.upper()
return ''.join(stringList)
I believe that, when I use words like 'apple' where there is two identical letters, the index() function can only manage to give me the index of the first 'p', if my word is apple.
It returns:
'APplE'
How could I fix this?
By iterating over the indices of the string, using the built-in function enumerate, together with the characters of the string (strings are also iterable):
def myfunc(mystring):
out = []
for i, c in enumerate(mystring):
if i % 2 == 0:
out.append(c.upper())
else:
out.append(c.lower())
return "".join(out)
Example output:
>>> myfunc('apple')
'ApPlE'
This is also a lot more efficient, since it only iterates over the string once. Your code iterates many times (each stringList.index call does a linear search for the letter).
If you want to make it a bit harder to read but re-use a bit more of what you already have, you can also use this, but I would not recommend it (as it iterates three times over the string, once to build the list and then twice to replace the characters):
def myfunc(mystring):
stringList = list(mystring)
stringList[::2] = map(str.upper, stringList[::2])
stringList[1::2] = map(str.lower, stringList[1::2])
return "".join(stringList)
The method list.index returns the index of the first occurence, making it unfit for recovering the index of the current element. Instead, you should use enumerate, this will allow you to get the expected result with a single list-comprehension.
def myFunc(s):
return ''.join([c.lower() if i % 2 else c.upper() for i, c in enumerate(s)])
print(myFunc('apple')) # ApPlE
I'm trying to print each element individually, which is fine but also repeat each element based on position eg. "abcd" = A-Bb-Ccc-Dddd etc
So my problems are making print statements print x times based off their position in the string. I've tried a few combinations using len and range but i often encounter errors because i'm using strings not ints.
Should i be using len and range here? I'd prefer if you guys didn't post finished code, just basically how to go about that specific problem (if possible) so i can still go about figuring it out myself.
user_string = input()
def accum(s):
for letter in s:
pos = s[0]
print(letter.title())
pos = s[0 + 1]
accum(user_string)
You can enumerate iterables (lists, strings, ranges, dictkeys, ...) - it provides the index and a value:
text = "abcdef"
for idx,c in enumerate(text):
print(idx,c)
Output:
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')
You can use that to print something multiple times. The print command takes 2 optional parameters :
print("Bla","blubb", sep=" --->", end=" Kawumm\n")
Output:
Bla --->blubb Kawumm
that specify what is printed between outputs and on the end of output - you can specify an end="" - so you can continue printing on the same line.
Doku:
Print
Enumerate
Edit:
user_string = input()
def accum(s):
t = [] # list to store stuff into
for count, letter in enumerate(s):
total = letter.upper() + letter * (count) # 1st as Upper, rest as is
t.append(total) # add to list
print(*t, sep="-") # the * "unpacks" the list into its parts
accum(user_string)
Unpacking:
print( [1,2,3,4,5], sep=" +++ ") # its just 1 value to print, no sep needed
print(*[1,2,3,4,5], sep=" +++ ") # 5 values to print, sep needed
Output:
[1, 2, 3, 4, 5]
1 +++ 2 +++ 3 +++ 4 +++ 5
You could try having a counter that will increase by 1 as the loop traverses through the string. Then, within the loop that you currently have, have another for loop to loop the size of the counter. If you want it to print out the first letter capitalized then you will need to account for that along with the dashes.
I have a nested list, with every second element having varying lengths:
lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]]
My output is a csv of dataframe with this look:
comparison similarity_score
a:e *some score
a:i *some score
a:o *some score
e:i *some score
e:o *some score
i:o *some score
my code:
similarity = []
for i in lst:
name = i[0]
string = i[1]
score = 0.0
length =(len(string))
for i in range(length):
if string[i]==string[i+1]:
score += 1.0
new_score = (100.0*score)/length
name_seq = name[i] + ':' + name[i+1]
similarity.append(name_seq,new_score)
similarity.pdDataFrame(similarity, columns = ['comparison' , 'similarity_score'])
similarity.to_csv('similarity_score.csv')
but I am recieving an error:
if codes[i]==codes[i+1]:
IndexError: string index out of range
any advice? thanks!
According to Python's documentation range does the following by example:
>>>range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In your code (assuming variable names have not changed):
...
length =(len(string)) # For an input of 'bcb' length will be 3
for i in range(length): # For an input of 'bcb' range will be [0, 1, 2]
if string[i]==string[i+1]: # When i == 2 i + 1 == 3 which gives you the
# IndexError: string index out of range
...
In other words, given an input bcb, your if statement will look at the following indices:
(0, 1)
(1, 2)
(2, 3) <-- The 3 in this case is your issue.
To fix your issue iterate from [0, len(string) - 1]
I think your biggest issue is that at the top level you're just iterating on one name,string pair at a time, not a pair of name,string pairs like you want to see in your output (as shown by the paired names a:e).
You're trying to index the name and string values later on, but doing so is not achieving what you want (comparing two strings to each other to compute a score), since you're only accessing adjacent characters in the same string. The exception you're getting is because i+1 may go off the end of the string. There's further confusion since you're using i for both the index in the inner loop and as the items taken from the outer loop (the name, string pairs).
To get pairs of pairs, I suggest using itertools.combinations:
import itertools
for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):
Now you can use the two name and two string variables in the rest of the loop.
I'm not entirely sure I understand how you want to compare the strings to get your score, since they're not the same length as one another. If you want to compare just the initial parts of the strings (and ignore the trailing bit of the longer one), you could use zip to get pairs of corresponding characters between the two strings. You can then compare them in a generator expression and add up the bool results (True is a special version of the integer 1 and False is a version of 0). You can then divide by the smaller of the string's lengths (or maybe the larger if you want to penalize length differences):
common_letters = sum(c1 == c2 for c1, c2 in zip(string1, string2))
new_score = common_letters * 100 / min(len(string1), len(string2))
There's one more obvious issue, where you're calling append with two arguments. If you really want to be appending a 2-tuple, you need an extra set of parentheses:
similarity.append((name_seq, new_score))
So, I'm trying to create a sudoku solver. Now, I want to check if a number is in it's line, column and square. Can I do it without introducing the line, column and square as function parameters? Is there any way to select the lists that contain an item? Here's my code:
sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
line1 = [sudoku[0],sudoku[1],sudoku[2],sudoku[3]]
column1 = [sudoku[0],sudoku[4],sudoku[8],sudoku[12]]
square1 = [sudoku[0],sudoku[1],sudoku[4],sudoku[5]]
def sudoku_cellsolver(x):
while sudoku[x] == 0:
number = sudoku[x]+1
if number not in #"List, column, square":
sudoku[x] = number
else:
number = number + 1
#Check another time, etc
while sudoku[x] != 0:
sudoku_cellsolver(x+1)
Any help welcomed. I also have an error when the second branch gets out of range, but I will deal with it later.
EDIT:
Pseudocode:
sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
l1 = {sudoku[0],sudoku[1],sudoku[2],sudoku[3]} #Converted to set
c1 = {sudoku[0],sudoku[4],sudoku[8],sudoku[12]} #Converted to set
sq1 = {sudoku[0],sudoku[1],sudoku[4],sudoku[5]} #Converted to set
group0 = [l1 | c1 | sq1] #Concatenation of sets
def sudoku_cellsolver(x,group):
if sudoku[x] == 0:
number = sudoku[x]+1
if number not in group:
sudoku[x] = number
The main problem is that I can't use a loop to solve one gap after another because I can't modify the parameter "group0" so that it changes to "group1" inside the function, something I can do with "sudoku[0]" to "sudoku[1]" using the "sudoku[x] = sudoku[x+1]".
If there's no way to change from "group0" to "group1" from inside the function, I'll have to define 16 almost-equal functions where only the "group" changes, and executing them from another function that uses an "if" statement to decide which one of the 16 functions is executed.
Your line1, column1, and square1 variables look like they're defined at the global level, so you should be able to access them like any other variable. You're on the right track with the if thing not in list construct. Try concatenating the lists together to build one list that you can check for membership:
if number not in line1 + column1 + square1:
sudoku[x] = number
This won't work for you if you need to be able to determine which of those lists number is in, but it doesn't look like you wanted to do that anyway.
If you want to modify your globals within a function, you will need to use the global keyword as described in this SO answer.
EDIT (based on comments)
It now appears that you're looking for the zip() function. Zip() groups elements from multiple iterables together by their index. Example:
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
groups = zip(a, b, c)
for i in xrange(3):
print(groups[i])
Outputs this:
(1, 4, 7)
(2, 5, 8)
(3, 6, 9)
Can you use zip() to group your elements together?