Python lists and ranges - python-3.x

I'm trying to practice my python so I can improve. I'm kinda stuck and not sure how to proceed. I get an error saying "can only concatenate list(not 'int') to list." I'll leave my code and what I'm trying to do below.
Input a word string (word)
find the string length of word
use range() to iterate through each letter in word (can use to range loops)
Save odd and even letters from the word as lists
odd_letters: starting at index 0,2,...
even_letters: starting at index 1,3,...
print odd and even lists
word = input("Type: ")
word = list(word)
print(word)
odd_letters = []
even_letters = []
length = int(len(word))
for i in range(length):
if i/2 == 0:
even_letters = even_letters + i
elif i/2 != 0:
odd_letters = odd_letters + i
print(even_letters)
print(odd_letters)

I wrote this... Let me know what you think...
word = input("Choose a word to test: ")
word_len = len(word)
print(word," contains ",word_len," letters")
odd_letters = []
even_letters = []
for i in range(1,len(word),2):
even_letters.append(word[i])
for i in range(0,word_len,2):
odd_letters.append(word[i])
print("Odd letters are: ",odd_letters)
print("Even letters are: ",even_letters)

Your code is good, but i decided to find a quicker solution for the program you want. This is my code:
word = str(input("Enter word:"))
store_1 = [x for x in word]
store_2 = []
for idx, val in enumerate(store_1):
store_2.append(idx)
even_numbers = [y for y in store_2 if y%2 == 0]
odd_numbers = [z for z in store_2 if z%2 == 1]
print("List of Even numbers:",even_numbers)
print("List of Odd numbers:",odd_numbers)
The variable 'word' takes in the word from the user. The list 'store_1' uses list comprehension to separate the letters the in the word and store it. Next, i enumerate through 'store_1' and use the variable 'store_2' to only store the indexes of 'store_1'.
Next, I declare another variable 'even_numbers' that uses list comprehension to iterate through 'store_2' and find the even numbers. The next variable 'odd_numbers' also uses list comprehension to find the odd numbers in 'store_2'.
Then, it just prints the even and odd lists to the user. Hope this helps :)

You cannot add an integer to a list, as you have attempted to do here:
even_letters = even_letters + i
You can instead do this (which is now adding a list to a list, which is valid):
even_letters = even_letters + [i]
Or, use append to alter the list in-place, adding the new element to the end:
even_letters.append(i)

Few things:
You cannot "add" an integer directly to a list using '+'. Using append() would be best.
str and str types can be concatenated using '+' so you could change odd_letters and even_letters to str as shown below.
also, by adding 'i' to even and odd, you are adding the iteration variable value.
Since you want the letter to be appended, you need to refer the list index i.e word[i]
and the first letter of what is entered will be at an odd position :)
word = input("Type: ")
word = list(word)
print(word)
odd_letters = ''
even_letters = ''
length = int(len(word))
for i in range(1,length+1):
if i%2 == 0:
even_letters = even_letters + word[i-1]
else:
odd_letters = odd_letters + word[i-1]
print("even_letters",even_letters)
print("odd_letters",odd_letters)

word=input()
word_num=len(word)
print(word_num)
odd_num=[]
even_num=[]
for letters in range(0,word_num,2):
odd_num.append(word[letters])
for letters in range(1,word_num,2):
even_num.append(word[letters])
print(odd_num)
print(even_num)
This is the answer it works with every word, and follows all the requirements.

Related

Is there a way to make this code more efficient whitout o(n^2)

The qustion is:
given the List of strings called "string_list" which contains:
string_list = ["darpa","da","arprpa"]
you need to make a new list, called my_list, that contains all the 3 length possible strings in each word of the string_list:
my_list = ['dar', 'arp', 'rpa', 'arp', 'rpr', 'prp', 'rpa']
string_list = ["darpa","da","arprpa"]
new_list = []
for word in string_list:
if len(word) >=3:
i=0
for char in word:
if len(word[i:i+3]) == 3:
new_list.append(word[i:i+3])
i = i+1
print(new_list)
My question is:
1. did i solve it in the best efficient way? (i know its o(n^2))
2. Which code will be the most efficient and maybe the shortest for this given task.
thank you!
You can shorten it and omit if's if you only use words that are lenght 3 to begin with:
string_list = ["darpa","da","arprpa"]
# as list comp
k1 = [word[start:start+3] for word in string_list for start in range(len(word)-2)]
# written out
k2 = []
for word in string_list:
lw = len(word)
for start in range(lw-2): # eliminates words shorter then 3 automatically,
# range(0) or less is valid but does not enter the loop
k2.append(word[start:start+3]) # this also removes the manual counter
print(k1)
print(k2)
Output (identical):
['dar', 'arp', 'rpa', 'arp', 'rpr', 'prp', 'rpa']

How to shuffle two strings to a set of string in Python3

How can I shuffle two strings s||t (shuffle(s, t)) with the given requirement that the first char always stands in front of the second one in s and t as well no matter we shuffle. The result returns as a set of strings without duplicates.
I have the following test:
print(shuffle('ab', 'cd'))
Result:
['abcd', 'acbd', 'acdb', 'cabd', 'cadb', 'cdab']
Thanks a lot.
This method will shuffle two strings and return a list of shuffles between them where the order of the characters is the same as in the original strings. If there are duplicate characters there will be duplicate results as well.
def shuffle(s1, s2):
if len(s1) == 1:
return [s2[:i] + s1 + s2[i:] for i in range(len(s2) + 1)]
if len(s2) == 1:
return [s1[:i] + s2 + s1[i:] for i in range(len(s1) + 1)]
return [s1[0]+ s for s in shuffle(s1[1:], s2)] + [s2[0] + s for s in shuffle(s1, s2[1:])]
print shuffle("ab", "cd")
It works by getting the first character of each string and recursively shuffling the rest and adding this character to each element in the list. When there is one character remaining on each of the strings it returns a list where the character is added in each position of the other string. Hope it helps.
So you can apply a condition on final shuffled list to generate a new list from the shuffled one:
S=shuffle('ab','cd')
nl=[]
for w in S:
if(w.index('a')<w.index('b') and w.index('c')<w.index('d')):
nl.append(w)
So nl is your new list as per your requirement:)
If I understood the question correctly, this should work. Note, as you add letters to this, it becomes a long running problem. 4 letters have 6 possible combination for each entry in the list. 8 letters have 5,040 possible combinations for each entry in the list.
import random
import math
InputList = ['ab','cd']
PossibleUniqueCombinations = math.factorial(len("".join(InputList))-1)
print (PossibleUniqueCombinations)
TargetList = []
UniqueCombinationList = []
for lst in InputList:
UniqueCnt = 0
FirstChar = lst[0]
TheRest = list(lst[1:])
while UniqueCnt < PossibleUniqueCombinations:
if InputList.index(lst) == 0:
LeftList = []
else:
LeftList = InputList[0:InputList.index(lst)]
RightList = list(InputList[InputList.index(lst)+1:])
TargetList = LeftList + TheRest + RightList
TargetStr = ''.join(TargetList)
TargetStr = ''.join(random.sample(TargetStr, len(TargetStr)))
ShuffledStr = FirstChar + ''.join(TargetStr)
try:
FndIdx = UniqueCombinationList.index(ShuffledStr)
except ValueError:
UniqueCombinationList.append(ShuffledStr)
UniqueCnt += 1
for combo in UniqueCombinationList:
print(combo)

Find anagrams of a given sentence from a list of words

I have a sentence with no spaces and only lowercase letters, for example:
"johndrinksmilk"
and a list of words, which contains only words that could be anagrams of the sentence above, also these words are in alphabetical order, for example:
["drink","drinks","john","milk","milks"]
I want to create a function (without using libraries) which returns a tuple of three words that together can form the anagram of the given sentence. This tuple has to be the last possible anagram of the sentence. If the words in the given list can't be used to form the given sentence, the function should return None. Since I know I'm very bad at explaining things I'll try to give you some examples:
For example, with:
sentence = "johndrinksmilk"
g_list = ["drink","drinks","john","milk","milks"]
the result should be:
r_result = ("milks","john","drink")
while these results should be wrong:
w_result = ("drinks","john","milk")
w_result = None
w_result = ("drink","john","milks")
I tried this:
def find_anagram(sentence, g_list):
g_list.reverse()
for fword in g_list:
if g_list.index(fword) == len(g_list)-1:
break
for i in range(len(fword)):
sentence_1 = sentence.replace(fword[i],"",1)
if sentence_1 == "":
break
count2 = g_list.index(fword)+1
for sword in g_list[count2:]:
if g_list.index(sword) == len(g_list)-1:
break
for i in range(len(sword)):
if sword.count(sword[i]) > sentence_1.count(sword[i]):
break
else:
sentence_2 = sentence_1.replace(sword[i],"",1)
count3 = g_list.index(sword)+1
if sentence_2 == "":
break
for tword in g_list[count3:]:
for i in range(len(tword)):
if tword.count(tword[i]) != sentence_2.count(tword[i]):
break
else:
return (fword,sword,tword)
return None
but instead of returning:
("milks","john","drink")
it returns:
None
Can anyone please tell me what's wrong? If you think my function is bad feel free to show me a different approach (but still without using libraries), because I have the feeling my function is both complex and very slow (and wrong of course...).
Thanks for your time.
Edit: new examples as requested.
sentence = "markeatsbread"
a_list = ["bread","daerb","eats","kram","mark","stae"] #these are all the possibles anagrams
the correct result is:
result = ["stae","mark","daerb"]
wrong results should be:
result = ["mark","eats","bread"] #this could be a possible anagram, but I need the last possible one
result = None #can't return None because there's at least one anagram
Try this and see if it works with all of your cases:
def findAnagram(sentence, word_list):
word_list.reverse()
for f_word in word_list:
if word_list[-1] == f_word:
break
index1 = word_list.index(f_word) + 1
for s_word in word_list[index1:]:
if word_list[-1] == s_word: break
index2 = word_list.index(s_word) + 1
for t_word in word_list[index2:]:
if (sorted(list(f_word + s_word + t_word)) == sorted(list(sentence))):
return (f_word, s_word, t_word)
Hopefully this helps you

Item assignment in a list of lists using a for loop

Print all the ways of arranging the letters in a word.
Given a word, print every possible rearrangement of the letters in the word.
word = input("Write your word:")
My attempt is below:
The factorial of len(word) provides the number of permutations.
count = 1
i = len(word)
while i > 0:
count *= i
i-=1
factorial = count # i!
f_minus = int(count/len(word)) # (i - 1)!
print("There are " + str(count) + " ways to arrange " + str(len(word)) \
+ " letters.")
Create a list to append rearranged words.
inside_list = []
for i in range(len(word)):
inside_list.append('')
Create a List to contain each inside_list.
container_list = []
for i in range(factorial):
container_list.append(inside_list)
The variable f_minus provides details about how many times each letter appears at the start of the word . Sticking with 'farm', f_minus = (4-1)! = 6. This tells us that each letter appears in the first position six times. The following for loop prints 'f' six times, followed by six 'a's and so on.
for index in range(factorial):
print(index + 1, word[index//f_minus])
So the following for loop assigns letters to the first element of each nested list.
for index in range(factorial):
container_list[index][0] = word[index//f_minus]
print(container_list)
How can I save the iterations to the list of lists so that the 'f's, 'a's, 'r's and 'm's go into the first element of the nested lists rather than all 'm's? i.e. the first 6 lists have an 'f' as their first element, the next 6 lists have an 'a' as the first element and so on.
There is already a function called permutations in itertools library for this purpose. You can use that instead of re-inventing the wheel.
from itertools import permutations
word = input("Write your word:")
print (["".join(wd) for wd in permutations(word, len(word))])
>>> Write your word:asd
>>> ['asd', 'ads', 'sad', 'sda', 'das', 'dsa']

python3 Why does max( listOfStrings) not return the longest element? [duplicate]

I have a list of variable length and am trying to find a way to test if the list item currently being evaluated is the longest string contained in the list. And I am using Python 2.6.1
For example:
mylist = ['abc','abcdef','abcd']
for each in mylist:
if condition1:
do_something()
elif ___________________: #else if each is the longest string contained in mylist:
do_something_else()
Surely there's a simple list comprehension that's short and elegant that I'm overlooking?
From the Python documentation itself, you can use max:
>>> mylist = ['123','123456','1234']
>>> print max(mylist, key=len)
123456
def longestWord(some_list):
count = 0 #You set the count to 0
for i in some_list: # Go through the whole list
if len(i) > count: #Checking for the longest word(string)
count = len(i)
word = i
return ("the longest string is " + word)
or much easier:
max(some_list , key = len)
What should happen if there are more than 1 longest string (think '12', and '01')?
Try that to get the longest element
max_length,longest_element = max([(len(x),x) for x in ('a','b','aa')])
And then regular foreach
for st in mylist:
if len(st)==max_length:...
To get the smallest or largest item in a list, use the built-in min and max functions:
lo = min(L)
hi = max(L)
As with sort, you can pass in a "key" argument that is used to map the list items before they are compared:
lo = min(L, key=int)
hi = max(L, key=int)
http://effbot.org/zone/python-list.htm
Looks like you could use the max function if you map it correctly for strings and use that as the comparison. I would recommend just finding the max once though of course, not for each element in the list.
len(each) == max(len(x) for x in myList) or just each == max(myList, key=len)
def LongestEntry(lstName):
totalEntries = len(lstName)
currentEntry = 0
longestLength = 0
while currentEntry < totalEntries:
thisEntry = len(str(lstName[currentEntry]))
if int(thisEntry) > int(longestLength):
longestLength = thisEntry
longestEntry = currentEntry
currentEntry += 1
return longestLength

Resources